LCOV - code coverage report
Current view: top level - lib - nlattr.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 73 294 24.8 %
Date: 2022-03-28 16:04:14 Functions: 9 26 34.6 %
Branches: 38 286 13.3 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * NETLINK      Netlink attributes
       4                 :            :  *
       5                 :            :  *              Authors:        Thomas Graf <tgraf@suug.ch>
       6                 :            :  *                              Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
       7                 :            :  */
       8                 :            : 
       9                 :            : #include <linux/export.h>
      10                 :            : #include <linux/kernel.h>
      11                 :            : #include <linux/errno.h>
      12                 :            : #include <linux/jiffies.h>
      13                 :            : #include <linux/skbuff.h>
      14                 :            : #include <linux/string.h>
      15                 :            : #include <linux/types.h>
      16                 :            : #include <net/netlink.h>
      17                 :            : 
      18                 :            : /* For these data types, attribute length should be exactly the given
      19                 :            :  * size. However, to maintain compatibility with broken commands, if the
      20                 :            :  * attribute length does not match the expected size a warning is emitted
      21                 :            :  * to the user that the command is sending invalid data and needs to be fixed.
      22                 :            :  */
      23                 :            : static const u8 nla_attr_len[NLA_TYPE_MAX+1] = {
      24                 :            :         [NLA_U8]        = sizeof(u8),
      25                 :            :         [NLA_U16]       = sizeof(u16),
      26                 :            :         [NLA_U32]       = sizeof(u32),
      27                 :            :         [NLA_U64]       = sizeof(u64),
      28                 :            :         [NLA_S8]        = sizeof(s8),
      29                 :            :         [NLA_S16]       = sizeof(s16),
      30                 :            :         [NLA_S32]       = sizeof(s32),
      31                 :            :         [NLA_S64]       = sizeof(s64),
      32                 :            : };
      33                 :            : 
      34                 :            : static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = {
      35                 :            :         [NLA_U8]        = sizeof(u8),
      36                 :            :         [NLA_U16]       = sizeof(u16),
      37                 :            :         [NLA_U32]       = sizeof(u32),
      38                 :            :         [NLA_U64]       = sizeof(u64),
      39                 :            :         [NLA_MSECS]     = sizeof(u64),
      40                 :            :         [NLA_NESTED]    = NLA_HDRLEN,
      41                 :            :         [NLA_S8]        = sizeof(s8),
      42                 :            :         [NLA_S16]       = sizeof(s16),
      43                 :            :         [NLA_S32]       = sizeof(s32),
      44                 :            :         [NLA_S64]       = sizeof(s64),
      45                 :            : };
      46                 :            : 
      47                 :          0 : static int validate_nla_bitfield32(const struct nlattr *nla,
      48                 :            :                                    const u32 *valid_flags_mask)
      49                 :            : {
      50                 :          0 :         const struct nla_bitfield32 *bf = nla_data(nla);
      51                 :            : 
      52         [ #  # ]:          0 :         if (!valid_flags_mask)
      53                 :            :                 return -EINVAL;
      54                 :            : 
      55                 :            :         /*disallow invalid bit selector */
      56         [ #  # ]:          0 :         if (bf->selector & ~*valid_flags_mask)
      57                 :            :                 return -EINVAL;
      58                 :            : 
      59                 :            :         /*disallow invalid bit values */
      60         [ #  # ]:          0 :         if (bf->value & ~*valid_flags_mask)
      61                 :            :                 return -EINVAL;
      62                 :            : 
      63                 :            :         /*disallow valid bit values that are not selected*/
      64         [ #  # ]:          0 :         if (bf->value & ~bf->selector)
      65                 :            :                 return -EINVAL;
      66                 :            : 
      67                 :            :         return 0;
      68                 :            : }
      69                 :            : 
      70                 :          0 : static int nla_validate_array(const struct nlattr *head, int len, int maxtype,
      71                 :            :                               const struct nla_policy *policy,
      72                 :            :                               struct netlink_ext_ack *extack,
      73                 :            :                               unsigned int validate)
      74                 :            : {
      75                 :          0 :         const struct nlattr *entry;
      76                 :          0 :         int rem;
      77                 :            : 
      78         [ #  # ]:          0 :         nla_for_each_attr(entry, head, len, rem) {
      79                 :          0 :                 int ret;
      80                 :            : 
      81         [ #  # ]:          0 :                 if (nla_len(entry) == 0)
      82                 :          0 :                         continue;
      83                 :            : 
      84         [ #  # ]:          0 :                 if (nla_len(entry) < NLA_HDRLEN) {
      85         [ #  # ]:          0 :                         NL_SET_ERR_MSG_ATTR(extack, entry,
      86                 :            :                                             "Array element too short");
      87                 :          0 :                         return -ERANGE;
      88                 :            :                 }
      89                 :            : 
      90                 :          0 :                 ret = __nla_validate(nla_data(entry), nla_len(entry),
      91                 :            :                                      maxtype, policy, validate, extack);
      92         [ #  # ]:          0 :                 if (ret < 0)
      93                 :          0 :                         return ret;
      94                 :            :         }
      95                 :            : 
      96                 :            :         return 0;
      97                 :            : }
      98                 :            : 
      99                 :          0 : static int nla_validate_int_range(const struct nla_policy *pt,
     100                 :            :                                   const struct nlattr *nla,
     101                 :            :                                   struct netlink_ext_ack *extack)
     102                 :            : {
     103                 :          0 :         bool validate_min, validate_max;
     104                 :          0 :         s64 value;
     105                 :            : 
     106                 :          0 :         validate_min = pt->validation_type == NLA_VALIDATE_RANGE ||
     107                 :            :                        pt->validation_type == NLA_VALIDATE_MIN;
     108                 :          0 :         validate_max = pt->validation_type == NLA_VALIDATE_RANGE ||
     109                 :            :                        pt->validation_type == NLA_VALIDATE_MAX;
     110                 :            : 
     111   [ #  #  #  #  :          0 :         switch (pt->type) {
             #  #  #  #  
                      # ]
     112                 :            :         case NLA_U8:
     113                 :          0 :                 value = nla_get_u8(nla);
     114                 :          0 :                 break;
     115                 :            :         case NLA_U16:
     116                 :          0 :                 value = nla_get_u16(nla);
     117                 :          0 :                 break;
     118                 :            :         case NLA_U32:
     119                 :          0 :                 value = nla_get_u32(nla);
     120                 :          0 :                 break;
     121                 :            :         case NLA_S8:
     122                 :          0 :                 value = nla_get_s8(nla);
     123                 :          0 :                 break;
     124                 :            :         case NLA_S16:
     125                 :          0 :                 value = nla_get_s16(nla);
     126                 :          0 :                 break;
     127                 :            :         case NLA_S32:
     128                 :          0 :                 value = nla_get_s32(nla);
     129                 :          0 :                 break;
     130                 :            :         case NLA_S64:
     131                 :          0 :                 value = nla_get_s64(nla);
     132                 :          0 :                 break;
     133                 :          0 :         case NLA_U64:
     134                 :            :                 /* treat this one specially, since it may not fit into s64 */
     135   [ #  #  #  #  :          0 :                 if ((validate_min && nla_get_u64(nla) < pt->min) ||
                   #  # ]
     136         [ #  # ]:          0 :                     (validate_max && nla_get_u64(nla) > pt->max)) {
     137         [ #  # ]:          0 :                         NL_SET_ERR_MSG_ATTR(extack, nla,
     138                 :            :                                             "integer out of range");
     139                 :          0 :                         return -ERANGE;
     140                 :            :                 }
     141                 :            :                 return 0;
     142                 :            :         default:
     143                 :          0 :                 WARN_ON(1);
     144                 :          0 :                 return -EINVAL;
     145                 :            :         }
     146                 :            : 
     147   [ #  #  #  #  :          0 :         if ((validate_min && value < pt->min) ||
                   #  # ]
     148         [ #  # ]:          0 :             (validate_max && value > pt->max)) {
     149         [ #  # ]:          0 :                 NL_SET_ERR_MSG_ATTR(extack, nla,
     150                 :            :                                     "integer out of range");
     151                 :          0 :                 return -ERANGE;
     152                 :            :         }
     153                 :            : 
     154                 :            :         return 0;
     155                 :            : }
     156                 :            : 
     157                 :        104 : static int validate_nla(const struct nlattr *nla, int maxtype,
     158                 :            :                         const struct nla_policy *policy, unsigned int validate,
     159                 :            :                         struct netlink_ext_ack *extack)
     160                 :            : {
     161                 :        104 :         u16 strict_start_type = policy[0].strict_start_type;
     162                 :        104 :         const struct nla_policy *pt;
     163         [ -  + ]:        104 :         int minlen = 0, attrlen = nla_len(nla), type = nla_type(nla);
     164                 :        104 :         int err = -ERANGE;
     165                 :            : 
     166   [ -  +  -  - ]:        104 :         if (strict_start_type && type >= strict_start_type)
     167                 :          0 :                 validate |= NL_VALIDATE_STRICT;
     168                 :            : 
     169         [ +  - ]:        104 :         if (type <= 0 || type > maxtype)
     170                 :            :                 return 0;
     171                 :            : 
     172                 :        104 :         pt = &policy[type];
     173                 :            : 
     174         [ -  + ]:        104 :         BUG_ON(pt->type > NLA_TYPE_MAX);
     175                 :            : 
     176   [ +  +  +  -  :        104 :         if ((nla_attr_len[pt->type] && attrlen != nla_attr_len[pt->type]) ||
                   -  + ]
     177         [ #  # ]:          0 :             (pt->type == NLA_EXACT_LEN_WARN && attrlen != pt->len)) {
     178         [ #  # ]:          0 :                 pr_warn_ratelimited("netlink: '%s': attribute type %d has an invalid length.\n",
     179                 :            :                                     current->comm, type);
     180         [ #  # ]:          0 :                 if (validate & NL_VALIDATE_STRICT_ATTRS) {
     181         [ #  # ]:          0 :                         NL_SET_ERR_MSG_ATTR(extack, nla,
     182                 :            :                                             "invalid attribute length");
     183                 :          0 :                         return -EINVAL;
     184                 :            :                 }
     185                 :            :         }
     186                 :            : 
     187         [ -  + ]:        104 :         if (validate & NL_VALIDATE_NESTED) {
     188         [ #  # ]:          0 :                 if ((pt->type == NLA_NESTED || pt->type == NLA_NESTED_ARRAY) &&
     189         [ #  # ]:          0 :                     !(nla->nla_type & NLA_F_NESTED)) {
     190         [ #  # ]:          0 :                         NL_SET_ERR_MSG_ATTR(extack, nla,
     191                 :            :                                             "NLA_F_NESTED is missing");
     192                 :          0 :                         return -EINVAL;
     193                 :            :                 }
     194         [ #  # ]:          0 :                 if (pt->type != NLA_NESTED && pt->type != NLA_NESTED_ARRAY &&
     195         [ #  # ]:          0 :                     pt->type != NLA_UNSPEC && (nla->nla_type & NLA_F_NESTED)) {
     196         [ #  # ]:          0 :                         NL_SET_ERR_MSG_ATTR(extack, nla,
     197                 :            :                                             "NLA_F_NESTED not expected");
     198                 :          0 :                         return -EINVAL;
     199                 :            :                 }
     200                 :            :         }
     201                 :            : 
     202   [ -  -  -  -  :        104 :         switch (pt->type) {
          -  -  -  -  -  
                +  -  + ]
     203                 :          0 :         case NLA_EXACT_LEN:
     204         [ #  # ]:          0 :                 if (attrlen != pt->len)
     205                 :          0 :                         goto out_err;
     206                 :            :                 break;
     207                 :            : 
     208                 :          0 :         case NLA_REJECT:
     209   [ #  #  #  # ]:          0 :                 if (extack && pt->validation_data) {
     210                 :          0 :                         NL_SET_BAD_ATTR(extack, nla);
     211                 :          0 :                         extack->_msg = pt->validation_data;
     212                 :          0 :                         return -EINVAL;
     213                 :            :                 }
     214                 :          0 :                 err = -EINVAL;
     215                 :          0 :                 goto out_err;
     216                 :            : 
     217                 :          0 :         case NLA_FLAG:
     218         [ #  # ]:          0 :                 if (attrlen > 0)
     219                 :          0 :                         goto out_err;
     220                 :            :                 break;
     221                 :            : 
     222                 :          0 :         case NLA_BITFIELD32:
     223         [ #  # ]:          0 :                 if (attrlen != sizeof(struct nla_bitfield32))
     224                 :          0 :                         goto out_err;
     225                 :            : 
     226         [ #  # ]:          0 :                 err = validate_nla_bitfield32(nla, pt->validation_data);
     227                 :            :                 if (err)
     228                 :          0 :                         goto out_err;
     229                 :            :                 break;
     230                 :            : 
     231                 :          0 :         case NLA_NUL_STRING:
     232         [ #  # ]:          0 :                 if (pt->len)
     233                 :          0 :                         minlen = min_t(int, attrlen, pt->len + 1);
     234                 :            :                 else
     235                 :            :                         minlen = attrlen;
     236                 :            : 
     237   [ #  #  #  # ]:          0 :                 if (!minlen || memchr(nla_data(nla), '\0', minlen) == NULL) {
     238                 :          0 :                         err = -EINVAL;
     239                 :          0 :                         goto out_err;
     240                 :            :                 }
     241                 :            :                 /* fall through */
     242                 :            : 
     243                 :            :         case NLA_STRING:
     244         [ #  # ]:          0 :                 if (attrlen < 1)
     245                 :          0 :                         goto out_err;
     246                 :            : 
     247         [ #  # ]:          0 :                 if (pt->len) {
     248         [ #  # ]:          0 :                         char *buf = nla_data(nla);
     249                 :            : 
     250         [ #  # ]:          0 :                         if (buf[attrlen - 1] == '\0')
     251                 :          0 :                                 attrlen--;
     252                 :            : 
     253         [ #  # ]:          0 :                         if (attrlen > pt->len)
     254                 :          0 :                                 goto out_err;
     255                 :            :                 }
     256                 :            :                 break;
     257                 :            : 
     258                 :          0 :         case NLA_BINARY:
     259   [ #  #  #  # ]:          0 :                 if (pt->len && attrlen > pt->len)
     260                 :          0 :                         goto out_err;
     261                 :            :                 break;
     262                 :            : 
     263                 :          0 :         case NLA_NESTED:
     264                 :            :                 /* a nested attributes is allowed to be empty; if its not,
     265                 :            :                  * it must have a size of at least NLA_HDRLEN.
     266                 :            :                  */
     267         [ #  # ]:          0 :                 if (attrlen == 0)
     268                 :            :                         break;
     269         [ #  # ]:          0 :                 if (attrlen < NLA_HDRLEN)
     270                 :          0 :                         goto out_err;
     271         [ #  # ]:          0 :                 if (pt->validation_data) {
     272                 :          0 :                         err = __nla_validate(nla_data(nla), nla_len(nla), pt->len,
     273                 :            :                                              pt->validation_data, validate,
     274                 :            :                                              extack);
     275         [ #  # ]:          0 :                         if (err < 0) {
     276                 :            :                                 /*
     277                 :            :                                  * return directly to preserve the inner
     278                 :            :                                  * error message/attribute pointer
     279                 :            :                                  */
     280                 :            :                                 return err;
     281                 :            :                         }
     282                 :            :                 }
     283                 :            :                 break;
     284                 :          0 :         case NLA_NESTED_ARRAY:
     285                 :            :                 /* a nested array attribute is allowed to be empty; if its not,
     286                 :            :                  * it must have a size of at least NLA_HDRLEN.
     287                 :            :                  */
     288         [ #  # ]:          0 :                 if (attrlen == 0)
     289                 :            :                         break;
     290         [ #  # ]:          0 :                 if (attrlen < NLA_HDRLEN)
     291                 :          0 :                         goto out_err;
     292         [ #  # ]:          0 :                 if (pt->validation_data) {
     293                 :          0 :                         int err;
     294                 :            : 
     295                 :          0 :                         err = nla_validate_array(nla_data(nla), nla_len(nla),
     296                 :          0 :                                                  pt->len, pt->validation_data,
     297                 :            :                                                  extack, validate);
     298         [ #  # ]:          0 :                         if (err < 0) {
     299                 :            :                                 /*
     300                 :            :                                  * return directly to preserve the inner
     301                 :            :                                  * error message/attribute pointer
     302                 :            :                                  */
     303                 :            :                                 return err;
     304                 :            :                         }
     305                 :            :                 }
     306                 :            :                 break;
     307                 :            : 
     308                 :         13 :         case NLA_UNSPEC:
     309         [ -  + ]:         13 :                 if (validate & NL_VALIDATE_UNSPEC) {
     310         [ #  # ]:          0 :                         NL_SET_ERR_MSG_ATTR(extack, nla,
     311                 :            :                                             "Unsupported attribute");
     312                 :          0 :                         return -EINVAL;
     313                 :            :                 }
     314                 :            :                 /* fall through */
     315                 :            :         case NLA_MIN_LEN:
     316         [ -  + ]:         13 :                 if (attrlen < pt->len)
     317                 :          0 :                         goto out_err;
     318                 :            :                 break;
     319                 :            : 
     320                 :         91 :         default:
     321         [ -  + ]:         91 :                 if (pt->len)
     322                 :          0 :                         minlen = pt->len;
     323                 :            :                 else
     324                 :         91 :                         minlen = nla_attr_minlen[pt->type];
     325                 :            : 
     326         [ -  + ]:         91 :                 if (attrlen < minlen)
     327                 :          0 :                         goto out_err;
     328                 :            :         }
     329                 :            : 
     330                 :            :         /* further validation */
     331      [ -  -  + ]:        104 :         switch (pt->validation_type) {
     332                 :            :         case NLA_VALIDATE_NONE:
     333                 :            :                 /* nothing to do */
     334                 :            :                 break;
     335                 :          0 :         case NLA_VALIDATE_RANGE:
     336                 :            :         case NLA_VALIDATE_MIN:
     337                 :            :         case NLA_VALIDATE_MAX:
     338                 :          0 :                 err = nla_validate_int_range(pt, nla, extack);
     339         [ #  # ]:          0 :                 if (err)
     340                 :          0 :                         return err;
     341                 :            :                 break;
     342                 :          0 :         case NLA_VALIDATE_FUNCTION:
     343         [ #  # ]:          0 :                 if (pt->validate) {
     344                 :          0 :                         err = pt->validate(nla, extack);
     345         [ #  # ]:          0 :                         if (err)
     346                 :          0 :                                 return err;
     347                 :            :                 }
     348                 :            :                 break;
     349                 :            :         }
     350                 :            : 
     351                 :            :         return 0;
     352                 :          0 : out_err:
     353         [ #  # ]:          0 :         NL_SET_ERR_MSG_ATTR(extack, nla, "Attribute failed policy validation");
     354                 :            :         return err;
     355                 :            : }
     356                 :            : 
     357                 :        260 : static int __nla_validate_parse(const struct nlattr *head, int len, int maxtype,
     358                 :            :                                 const struct nla_policy *policy,
     359                 :            :                                 unsigned int validate,
     360                 :            :                                 struct netlink_ext_ack *extack,
     361                 :            :                                 struct nlattr **tb)
     362                 :            : {
     363                 :        260 :         const struct nlattr *nla;
     364                 :        260 :         int rem;
     365                 :            : 
     366         [ +  - ]:        260 :         if (tb)
     367                 :        260 :                 memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
     368                 :            : 
     369         [ +  + ]:        364 :         nla_for_each_attr(nla, head, len, rem) {
     370         [ +  - ]:        104 :                 u16 type = nla_type(nla);
     371                 :            : 
     372   [ -  +  +  - ]:        104 :                 if (type == 0 || type > maxtype) {
     373         [ #  # ]:          0 :                         if (validate & NL_VALIDATE_MAXTYPE) {
     374         [ #  # ]:          0 :                                 NL_SET_ERR_MSG_ATTR(extack, nla,
     375                 :            :                                                     "Unknown attribute type");
     376                 :          0 :                                 return -EINVAL;
     377                 :            :                         }
     378                 :          0 :                         continue;
     379                 :            :                 }
     380         [ +  - ]:        104 :                 if (policy) {
     381                 :        104 :                         int err = validate_nla(nla, maxtype, policy,
     382                 :            :                                                validate, extack);
     383                 :            : 
     384         [ -  + ]:        104 :                         if (err < 0)
     385                 :          0 :                                 return err;
     386                 :            :                 }
     387                 :            : 
     388         [ +  - ]:        104 :                 if (tb)
     389                 :        104 :                         tb[type] = (struct nlattr *)nla;
     390                 :            :         }
     391                 :            : 
     392         [ -  + ]:        260 :         if (unlikely(rem > 0)) {
     393         [ #  # ]:          0 :                 pr_warn_ratelimited("netlink: %d bytes leftover after parsing attributes in process `%s'.\n",
     394                 :            :                                     rem, current->comm);
     395         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "bytes leftover after parsing attributes");
     396         [ #  # ]:          0 :                 if (validate & NL_VALIDATE_TRAILING)
     397                 :          0 :                         return -EINVAL;
     398                 :            :         }
     399                 :            : 
     400                 :            :         return 0;
     401                 :            : }
     402                 :            : 
     403                 :            : /**
     404                 :            :  * __nla_validate - Validate a stream of attributes
     405                 :            :  * @head: head of attribute stream
     406                 :            :  * @len: length of attribute stream
     407                 :            :  * @maxtype: maximum attribute type to be expected
     408                 :            :  * @policy: validation policy
     409                 :            :  * @validate: validation strictness
     410                 :            :  * @extack: extended ACK report struct
     411                 :            :  *
     412                 :            :  * Validates all attributes in the specified attribute stream against the
     413                 :            :  * specified policy. Validation depends on the validate flags passed, see
     414                 :            :  * &enum netlink_validation for more details on that.
     415                 :            :  * See documenation of struct nla_policy for more details.
     416                 :            :  *
     417                 :            :  * Returns 0 on success or a negative error code.
     418                 :            :  */
     419                 :          0 : int __nla_validate(const struct nlattr *head, int len, int maxtype,
     420                 :            :                    const struct nla_policy *policy, unsigned int validate,
     421                 :            :                    struct netlink_ext_ack *extack)
     422                 :            : {
     423                 :          0 :         return __nla_validate_parse(head, len, maxtype, policy, validate,
     424                 :            :                                     extack, NULL);
     425                 :            : }
     426                 :            : EXPORT_SYMBOL(__nla_validate);
     427                 :            : 
     428                 :            : /**
     429                 :            :  * nla_policy_len - Determin the max. length of a policy
     430                 :            :  * @policy: policy to use
     431                 :            :  * @n: number of policies
     432                 :            :  *
     433                 :            :  * Determines the max. length of the policy.  It is currently used
     434                 :            :  * to allocated Netlink buffers roughly the size of the actual
     435                 :            :  * message.
     436                 :            :  *
     437                 :            :  * Returns 0 on success or a negative error code.
     438                 :            :  */
     439                 :            : int
     440                 :          0 : nla_policy_len(const struct nla_policy *p, int n)
     441                 :            : {
     442                 :          0 :         int i, len = 0;
     443                 :            : 
     444         [ #  # ]:          0 :         for (i = 0; i < n; i++, p++) {
     445         [ #  # ]:          0 :                 if (p->len)
     446                 :          0 :                         len += nla_total_size(p->len);
     447         [ #  # ]:          0 :                 else if (nla_attr_len[p->type])
     448                 :          0 :                         len += nla_total_size(nla_attr_len[p->type]);
     449         [ #  # ]:          0 :                 else if (nla_attr_minlen[p->type])
     450                 :          0 :                         len += nla_total_size(nla_attr_minlen[p->type]);
     451                 :            :         }
     452                 :            : 
     453                 :          0 :         return len;
     454                 :            : }
     455                 :            : EXPORT_SYMBOL(nla_policy_len);
     456                 :            : 
     457                 :            : /**
     458                 :            :  * __nla_parse - Parse a stream of attributes into a tb buffer
     459                 :            :  * @tb: destination array with maxtype+1 elements
     460                 :            :  * @maxtype: maximum attribute type to be expected
     461                 :            :  * @head: head of attribute stream
     462                 :            :  * @len: length of attribute stream
     463                 :            :  * @policy: validation policy
     464                 :            :  * @validate: validation strictness
     465                 :            :  * @extack: extended ACK pointer
     466                 :            :  *
     467                 :            :  * Parses a stream of attributes and stores a pointer to each attribute in
     468                 :            :  * the tb array accessible via the attribute type.
     469                 :            :  * Validation is controlled by the @validate parameter.
     470                 :            :  *
     471                 :            :  * Returns 0 on success or a negative error code.
     472                 :            :  */
     473                 :        260 : int __nla_parse(struct nlattr **tb, int maxtype,
     474                 :            :                 const struct nlattr *head, int len,
     475                 :            :                 const struct nla_policy *policy, unsigned int validate,
     476                 :            :                 struct netlink_ext_ack *extack)
     477                 :            : {
     478                 :        260 :         return __nla_validate_parse(head, len, maxtype, policy, validate,
     479                 :            :                                     extack, tb);
     480                 :            : }
     481                 :            : EXPORT_SYMBOL(__nla_parse);
     482                 :            : 
     483                 :            : /**
     484                 :            :  * nla_find - Find a specific attribute in a stream of attributes
     485                 :            :  * @head: head of attribute stream
     486                 :            :  * @len: length of attribute stream
     487                 :            :  * @attrtype: type of attribute to look for
     488                 :            :  *
     489                 :            :  * Returns the first attribute in the stream matching the specified type.
     490                 :            :  */
     491                 :          0 : struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype)
     492                 :            : {
     493                 :          0 :         const struct nlattr *nla;
     494                 :          0 :         int rem;
     495                 :            : 
     496         [ #  # ]:          0 :         nla_for_each_attr(nla, head, len, rem)
     497         [ #  # ]:          0 :                 if (nla_type(nla) == attrtype)
     498                 :          0 :                         return (struct nlattr *)nla;
     499                 :            : 
     500                 :            :         return NULL;
     501                 :            : }
     502                 :            : EXPORT_SYMBOL(nla_find);
     503                 :            : 
     504                 :            : /**
     505                 :            :  * nla_strlcpy - Copy string attribute payload into a sized buffer
     506                 :            :  * @dst: where to copy the string to
     507                 :            :  * @nla: attribute to copy the string from
     508                 :            :  * @dstsize: size of destination buffer
     509                 :            :  *
     510                 :            :  * Copies at most dstsize - 1 bytes into the destination buffer.
     511                 :            :  * The result is always a valid NUL-terminated string. Unlike
     512                 :            :  * strlcpy the destination buffer is always padded out.
     513                 :            :  *
     514                 :            :  * Returns the length of the source buffer.
     515                 :            :  */
     516                 :          0 : size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
     517                 :            : {
     518         [ #  # ]:          0 :         size_t srclen = nla_len(nla);
     519         [ #  # ]:          0 :         char *src = nla_data(nla);
     520                 :            : 
     521   [ #  #  #  # ]:          0 :         if (srclen > 0 && src[srclen - 1] == '\0')
     522                 :          0 :                 srclen--;
     523                 :            : 
     524         [ #  # ]:          0 :         if (dstsize > 0) {
     525         [ #  # ]:          0 :                 size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
     526                 :            : 
     527                 :          0 :                 memset(dst, 0, dstsize);
     528                 :          0 :                 memcpy(dst, src, len);
     529                 :            :         }
     530                 :            : 
     531                 :          0 :         return srclen;
     532                 :            : }
     533                 :            : EXPORT_SYMBOL(nla_strlcpy);
     534                 :            : 
     535                 :            : /**
     536                 :            :  * nla_strdup - Copy string attribute payload into a newly allocated buffer
     537                 :            :  * @nla: attribute to copy the string from
     538                 :            :  * @flags: the type of memory to allocate (see kmalloc).
     539                 :            :  *
     540                 :            :  * Returns a pointer to the allocated buffer or NULL on error.
     541                 :            :  */
     542                 :          0 : char *nla_strdup(const struct nlattr *nla, gfp_t flags)
     543                 :            : {
     544         [ #  # ]:          0 :         size_t srclen = nla_len(nla);
     545         [ #  # ]:          0 :         char *src = nla_data(nla), *dst;
     546                 :            : 
     547   [ #  #  #  # ]:          0 :         if (srclen > 0 && src[srclen - 1] == '\0')
     548                 :          0 :                 srclen--;
     549                 :            : 
     550         [ #  # ]:          0 :         dst = kmalloc(srclen + 1, flags);
     551         [ #  # ]:          0 :         if (dst != NULL) {
     552                 :          0 :                 memcpy(dst, src, srclen);
     553                 :          0 :                 dst[srclen] = '\0';
     554                 :            :         }
     555                 :          0 :         return dst;
     556                 :            : }
     557                 :            : EXPORT_SYMBOL(nla_strdup);
     558                 :            : 
     559                 :            : /**
     560                 :            :  * nla_memcpy - Copy a netlink attribute into another memory area
     561                 :            :  * @dest: where to copy to memcpy
     562                 :            :  * @src: netlink attribute to copy from
     563                 :            :  * @count: size of the destination area
     564                 :            :  *
     565                 :            :  * Note: The number of bytes copied is limited by the length of
     566                 :            :  *       attribute's payload. memcpy
     567                 :            :  *
     568                 :            :  * Returns the number of bytes copied.
     569                 :            :  */
     570                 :          0 : int nla_memcpy(void *dest, const struct nlattr *src, int count)
     571                 :            : {
     572         [ #  # ]:          0 :         int minlen = min_t(int, count, nla_len(src));
     573                 :            : 
     574         [ #  # ]:          0 :         memcpy(dest, nla_data(src), minlen);
     575         [ #  # ]:          0 :         if (count > minlen)
     576                 :          0 :                 memset(dest + minlen, 0, count - minlen);
     577                 :            : 
     578                 :          0 :         return minlen;
     579                 :            : }
     580                 :            : EXPORT_SYMBOL(nla_memcpy);
     581                 :            : 
     582                 :            : /**
     583                 :            :  * nla_memcmp - Compare an attribute with sized memory area
     584                 :            :  * @nla: netlink attribute
     585                 :            :  * @data: memory area
     586                 :            :  * @size: size of memory area
     587                 :            :  */
     588                 :          0 : int nla_memcmp(const struct nlattr *nla, const void *data,
     589                 :            :                              size_t size)
     590                 :            : {
     591         [ #  # ]:          0 :         int d = nla_len(nla) - size;
     592                 :            : 
     593         [ #  # ]:          0 :         if (d == 0)
     594                 :          0 :                 d = memcmp(nla_data(nla), data, size);
     595                 :            : 
     596                 :          0 :         return d;
     597                 :            : }
     598                 :            : EXPORT_SYMBOL(nla_memcmp);
     599                 :            : 
     600                 :            : /**
     601                 :            :  * nla_strcmp - Compare a string attribute against a string
     602                 :            :  * @nla: netlink string attribute
     603                 :            :  * @str: another string
     604                 :            :  */
     605                 :          0 : int nla_strcmp(const struct nlattr *nla, const char *str)
     606                 :            : {
     607                 :          0 :         int len = strlen(str);
     608         [ #  # ]:          0 :         char *buf = nla_data(nla);
     609         [ #  # ]:          0 :         int attrlen = nla_len(nla);
     610                 :          0 :         int d;
     611                 :            : 
     612   [ #  #  #  # ]:          0 :         if (attrlen > 0 && buf[attrlen - 1] == '\0')
     613                 :          0 :                 attrlen--;
     614                 :            : 
     615                 :          0 :         d = attrlen - len;
     616         [ #  # ]:          0 :         if (d == 0)
     617                 :          0 :                 d = memcmp(nla_data(nla), str, len);
     618                 :            : 
     619                 :          0 :         return d;
     620                 :            : }
     621                 :            : EXPORT_SYMBOL(nla_strcmp);
     622                 :            : 
     623                 :            : #ifdef CONFIG_NET
     624                 :            : /**
     625                 :            :  * __nla_reserve - reserve room for attribute on the skb
     626                 :            :  * @skb: socket buffer to reserve room on
     627                 :            :  * @attrtype: attribute type
     628                 :            :  * @attrlen: length of attribute payload
     629                 :            :  *
     630                 :            :  * Adds a netlink attribute header to a socket buffer and reserves
     631                 :            :  * room for the payload but does not copy it.
     632                 :            :  *
     633                 :            :  * The caller is responsible to ensure that the skb provides enough
     634                 :            :  * tailroom for the attribute header and payload.
     635                 :            :  */
     636                 :      17043 : struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
     637                 :            : {
     638                 :      17043 :         struct nlattr *nla;
     639                 :            : 
     640                 :      17043 :         nla = skb_put(skb, nla_total_size(attrlen));
     641                 :      17043 :         nla->nla_type = attrtype;
     642                 :      17043 :         nla->nla_len = nla_attr_size(attrlen);
     643                 :            : 
     644                 :      17043 :         memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
     645                 :            : 
     646                 :      17043 :         return nla;
     647                 :            : }
     648                 :            : EXPORT_SYMBOL(__nla_reserve);
     649                 :            : 
     650                 :            : /**
     651                 :            :  * __nla_reserve_64bit - reserve room for attribute on the skb and align it
     652                 :            :  * @skb: socket buffer to reserve room on
     653                 :            :  * @attrtype: attribute type
     654                 :            :  * @attrlen: length of attribute payload
     655                 :            :  * @padattr: attribute type for the padding
     656                 :            :  *
     657                 :            :  * Adds a netlink attribute header to a socket buffer and reserves
     658                 :            :  * room for the payload but does not copy it. It also ensure that this
     659                 :            :  * attribute will have a 64-bit aligned nla_data() area.
     660                 :            :  *
     661                 :            :  * The caller is responsible to ensure that the skb provides enough
     662                 :            :  * tailroom for the attribute header and payload.
     663                 :            :  */
     664                 :        338 : struct nlattr *__nla_reserve_64bit(struct sk_buff *skb, int attrtype,
     665                 :            :                                    int attrlen, int padattr)
     666                 :            : {
     667                 :          0 :         if (nla_need_padding_for_64bit(skb))
     668                 :            :                 nla_align_64bit(skb, padattr);
     669                 :            : 
     670                 :        338 :         return __nla_reserve(skb, attrtype, attrlen);
     671                 :            : }
     672                 :            : EXPORT_SYMBOL(__nla_reserve_64bit);
     673                 :            : 
     674                 :            : /**
     675                 :            :  * __nla_reserve_nohdr - reserve room for attribute without header
     676                 :            :  * @skb: socket buffer to reserve room on
     677                 :            :  * @attrlen: length of attribute payload
     678                 :            :  *
     679                 :            :  * Reserves room for attribute payload without a header.
     680                 :            :  *
     681                 :            :  * The caller is responsible to ensure that the skb provides enough
     682                 :            :  * tailroom for the payload.
     683                 :            :  */
     684                 :          0 : void *__nla_reserve_nohdr(struct sk_buff *skb, int attrlen)
     685                 :            : {
     686                 :          0 :         return skb_put_zero(skb, NLA_ALIGN(attrlen));
     687                 :            : }
     688                 :            : EXPORT_SYMBOL(__nla_reserve_nohdr);
     689                 :            : 
     690                 :            : /**
     691                 :            :  * nla_reserve - reserve room for attribute on the skb
     692                 :            :  * @skb: socket buffer to reserve room on
     693                 :            :  * @attrtype: attribute type
     694                 :            :  * @attrlen: length of attribute payload
     695                 :            :  *
     696                 :            :  * Adds a netlink attribute header to a socket buffer and reserves
     697                 :            :  * room for the payload but does not copy it.
     698                 :            :  *
     699                 :            :  * Returns NULL if the tailroom of the skb is insufficient to store
     700                 :            :  * the attribute header and payload.
     701                 :            :  */
     702                 :       1001 : struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
     703                 :            : {
     704   [ +  -  +  - ]:       2002 :         if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
     705                 :            :                 return NULL;
     706                 :            : 
     707                 :       1001 :         return __nla_reserve(skb, attrtype, attrlen);
     708                 :            : }
     709                 :            : EXPORT_SYMBOL(nla_reserve);
     710                 :            : 
     711                 :            : /**
     712                 :            :  * nla_reserve_64bit - reserve room for attribute on the skb and align it
     713                 :            :  * @skb: socket buffer to reserve room on
     714                 :            :  * @attrtype: attribute type
     715                 :            :  * @attrlen: length of attribute payload
     716                 :            :  * @padattr: attribute type for the padding
     717                 :            :  *
     718                 :            :  * Adds a netlink attribute header to a socket buffer and reserves
     719                 :            :  * room for the payload but does not copy it. It also ensure that this
     720                 :            :  * attribute will have a 64-bit aligned nla_data() area.
     721                 :            :  *
     722                 :            :  * Returns NULL if the tailroom of the skb is insufficient to store
     723                 :            :  * the attribute header and payload.
     724                 :            :  */
     725                 :        169 : struct nlattr *nla_reserve_64bit(struct sk_buff *skb, int attrtype, int attrlen,
     726                 :            :                                  int padattr)
     727                 :            : {
     728                 :        169 :         size_t len;
     729                 :            : 
     730         [ +  - ]:        169 :         if (nla_need_padding_for_64bit(skb))
     731                 :            :                 len = nla_total_size_64bit(attrlen);
     732                 :            :         else
     733         [ +  - ]:        169 :                 len = nla_total_size(attrlen);
     734   [ +  -  +  - ]:        338 :         if (unlikely(skb_tailroom(skb) < len))
     735                 :            :                 return NULL;
     736                 :            : 
     737                 :        169 :         return __nla_reserve_64bit(skb, attrtype, attrlen, padattr);
     738                 :            : }
     739                 :            : EXPORT_SYMBOL(nla_reserve_64bit);
     740                 :            : 
     741                 :            : /**
     742                 :            :  * nla_reserve_nohdr - reserve room for attribute without header
     743                 :            :  * @skb: socket buffer to reserve room on
     744                 :            :  * @attrlen: length of attribute payload
     745                 :            :  *
     746                 :            :  * Reserves room for attribute payload without a header.
     747                 :            :  *
     748                 :            :  * Returns NULL if the tailroom of the skb is insufficient to store
     749                 :            :  * the attribute payload.
     750                 :            :  */
     751                 :          0 : void *nla_reserve_nohdr(struct sk_buff *skb, int attrlen)
     752                 :            : {
     753   [ #  #  #  # ]:          0 :         if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
     754                 :            :                 return NULL;
     755                 :            : 
     756                 :          0 :         return __nla_reserve_nohdr(skb, attrlen);
     757                 :            : }
     758                 :            : EXPORT_SYMBOL(nla_reserve_nohdr);
     759                 :            : 
     760                 :            : /**
     761                 :            :  * __nla_put - Add a netlink attribute to a socket buffer
     762                 :            :  * @skb: socket buffer to add attribute to
     763                 :            :  * @attrtype: attribute type
     764                 :            :  * @attrlen: length of attribute payload
     765                 :            :  * @data: head of attribute payload
     766                 :            :  *
     767                 :            :  * The caller is responsible to ensure that the skb provides enough
     768                 :            :  * tailroom for the attribute header and payload.
     769                 :            :  */
     770                 :      15704 : void __nla_put(struct sk_buff *skb, int attrtype, int attrlen,
     771                 :            :                              const void *data)
     772                 :            : {
     773                 :      15704 :         struct nlattr *nla;
     774                 :            : 
     775                 :      15704 :         nla = __nla_reserve(skb, attrtype, attrlen);
     776                 :      15704 :         memcpy(nla_data(nla), data, attrlen);
     777                 :      15704 : }
     778                 :            : EXPORT_SYMBOL(__nla_put);
     779                 :            : 
     780                 :            : /**
     781                 :            :  * __nla_put_64bit - Add a netlink attribute to a socket buffer and align it
     782                 :            :  * @skb: socket buffer to add attribute to
     783                 :            :  * @attrtype: attribute type
     784                 :            :  * @attrlen: length of attribute payload
     785                 :            :  * @data: head of attribute payload
     786                 :            :  * @padattr: attribute type for the padding
     787                 :            :  *
     788                 :            :  * The caller is responsible to ensure that the skb provides enough
     789                 :            :  * tailroom for the attribute header and payload.
     790                 :            :  */
     791                 :        169 : void __nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
     792                 :            :                      const void *data, int padattr)
     793                 :            : {
     794                 :        169 :         struct nlattr *nla;
     795                 :            : 
     796                 :          0 :         nla = __nla_reserve_64bit(skb, attrtype, attrlen, padattr);
     797                 :        169 :         memcpy(nla_data(nla), data, attrlen);
     798                 :          0 : }
     799                 :            : EXPORT_SYMBOL(__nla_put_64bit);
     800                 :            : 
     801                 :            : /**
     802                 :            :  * __nla_put_nohdr - Add a netlink attribute without header
     803                 :            :  * @skb: socket buffer to add attribute to
     804                 :            :  * @attrlen: length of attribute payload
     805                 :            :  * @data: head of attribute payload
     806                 :            :  *
     807                 :            :  * The caller is responsible to ensure that the skb provides enough
     808                 :            :  * tailroom for the attribute payload.
     809                 :            :  */
     810                 :          0 : void __nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)
     811                 :            : {
     812                 :          0 :         void *start;
     813                 :            : 
     814                 :          0 :         start = __nla_reserve_nohdr(skb, attrlen);
     815                 :          0 :         memcpy(start, data, attrlen);
     816                 :          0 : }
     817                 :            : EXPORT_SYMBOL(__nla_put_nohdr);
     818                 :            : 
     819                 :            : /**
     820                 :            :  * nla_put - Add a netlink attribute to a socket buffer
     821                 :            :  * @skb: socket buffer to add attribute to
     822                 :            :  * @attrtype: attribute type
     823                 :            :  * @attrlen: length of attribute payload
     824                 :            :  * @data: head of attribute payload
     825                 :            :  *
     826                 :            :  * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store
     827                 :            :  * the attribute header and payload.
     828                 :            :  */
     829                 :      15704 : int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
     830                 :            : {
     831   [ +  -  +  - ]:      31408 :         if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
     832                 :            :                 return -EMSGSIZE;
     833                 :            : 
     834                 :      15704 :         __nla_put(skb, attrtype, attrlen, data);
     835                 :      15704 :         return 0;
     836                 :            : }
     837                 :            : EXPORT_SYMBOL(nla_put);
     838                 :            : 
     839                 :            : /**
     840                 :            :  * nla_put_64bit - Add a netlink attribute to a socket buffer and align it
     841                 :            :  * @skb: socket buffer to add attribute to
     842                 :            :  * @attrtype: attribute type
     843                 :            :  * @attrlen: length of attribute payload
     844                 :            :  * @data: head of attribute payload
     845                 :            :  * @padattr: attribute type for the padding
     846                 :            :  *
     847                 :            :  * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store
     848                 :            :  * the attribute header and payload.
     849                 :            :  */
     850                 :        169 : int nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
     851                 :            :                   const void *data, int padattr)
     852                 :            : {
     853                 :        169 :         size_t len;
     854                 :            : 
     855         [ +  - ]:        169 :         if (nla_need_padding_for_64bit(skb))
     856                 :            :                 len = nla_total_size_64bit(attrlen);
     857                 :            :         else
     858         [ +  - ]:        169 :                 len = nla_total_size(attrlen);
     859   [ +  -  +  - ]:        338 :         if (unlikely(skb_tailroom(skb) < len))
     860                 :            :                 return -EMSGSIZE;
     861                 :            : 
     862                 :        169 :         __nla_put_64bit(skb, attrtype, attrlen, data, padattr);
     863                 :        169 :         return 0;
     864                 :            : }
     865                 :            : EXPORT_SYMBOL(nla_put_64bit);
     866                 :            : 
     867                 :            : /**
     868                 :            :  * nla_put_nohdr - Add a netlink attribute without header
     869                 :            :  * @skb: socket buffer to add attribute to
     870                 :            :  * @attrlen: length of attribute payload
     871                 :            :  * @data: head of attribute payload
     872                 :            :  *
     873                 :            :  * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store
     874                 :            :  * the attribute payload.
     875                 :            :  */
     876                 :          0 : int nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)
     877                 :            : {
     878   [ #  #  #  # ]:          0 :         if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
     879                 :            :                 return -EMSGSIZE;
     880                 :            : 
     881                 :          0 :         __nla_put_nohdr(skb, attrlen, data);
     882                 :          0 :         return 0;
     883                 :            : }
     884                 :            : EXPORT_SYMBOL(nla_put_nohdr);
     885                 :            : 
     886                 :            : /**
     887                 :            :  * nla_append - Add a netlink attribute without header or padding
     888                 :            :  * @skb: socket buffer to add attribute to
     889                 :            :  * @attrlen: length of attribute payload
     890                 :            :  * @data: head of attribute payload
     891                 :            :  *
     892                 :            :  * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store
     893                 :            :  * the attribute payload.
     894                 :            :  */
     895                 :          0 : int nla_append(struct sk_buff *skb, int attrlen, const void *data)
     896                 :            : {
     897   [ #  #  #  # ]:          0 :         if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
     898                 :            :                 return -EMSGSIZE;
     899                 :            : 
     900                 :          0 :         skb_put_data(skb, data, attrlen);
     901                 :          0 :         return 0;
     902                 :            : }
     903                 :            : EXPORT_SYMBOL(nla_append);
     904                 :            : #endif

Generated by: LCOV version 1.14