linux/lib/nlattr.c
<<
>>
Prefs
   1/*
   2 * NETLINK      Netlink attributes
   3 *
   4 *              Authors:        Thomas Graf <tgraf@suug.ch>
   5 *                              Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
   6 */
   7
   8#include <linux/export.h>
   9#include <linux/kernel.h>
  10#include <linux/errno.h>
  11#include <linux/jiffies.h>
  12#include <linux/skbuff.h>
  13#include <linux/string.h>
  14#include <linux/types.h>
  15#include <net/netlink.h>
  16
  17static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = {
  18        [NLA_U8]        = sizeof(u8),
  19        [NLA_U16]       = sizeof(u16),
  20        [NLA_U32]       = sizeof(u32),
  21        [NLA_U64]       = sizeof(u64),
  22        [NLA_MSECS]     = sizeof(u64),
  23        [NLA_NESTED]    = NLA_HDRLEN,
  24        [NLA_S8]        = sizeof(s8),
  25        [NLA_S16]       = sizeof(s16),
  26        [NLA_S32]       = sizeof(s32),
  27        [NLA_S64]       = sizeof(s64),
  28};
  29
  30static int validate_nla(const struct nlattr *nla, int maxtype,
  31                        const struct nla_policy *policy)
  32{
  33        const struct nla_policy *pt;
  34        int minlen = 0, attrlen = nla_len(nla), type = nla_type(nla);
  35
  36        if (type <= 0 || type > maxtype)
  37                return 0;
  38
  39        pt = &policy[type];
  40
  41        BUG_ON(pt->type > NLA_TYPE_MAX);
  42
  43        switch (pt->type) {
  44        case NLA_FLAG:
  45                if (attrlen > 0)
  46                        return -ERANGE;
  47                break;
  48
  49        case NLA_NUL_STRING:
  50                if (pt->len)
  51                        minlen = min_t(int, attrlen, pt->len + 1);
  52                else
  53                        minlen = attrlen;
  54
  55                if (!minlen || memchr(nla_data(nla), '\0', minlen) == NULL)
  56                        return -EINVAL;
  57                /* fall through */
  58
  59        case NLA_STRING:
  60                if (attrlen < 1)
  61                        return -ERANGE;
  62
  63                if (pt->len) {
  64                        char *buf = nla_data(nla);
  65
  66                        if (buf[attrlen - 1] == '\0')
  67                                attrlen--;
  68
  69                        if (attrlen > pt->len)
  70                                return -ERANGE;
  71                }
  72                break;
  73
  74        case NLA_BINARY:
  75                if (pt->len && attrlen > pt->len)
  76                        return -ERANGE;
  77                break;
  78
  79        case NLA_NESTED_COMPAT:
  80                if (attrlen < pt->len)
  81                        return -ERANGE;
  82                if (attrlen < NLA_ALIGN(pt->len))
  83                        break;
  84                if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN)
  85                        return -ERANGE;
  86                nla = nla_data(nla) + NLA_ALIGN(pt->len);
  87                if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN + nla_len(nla))
  88                        return -ERANGE;
  89                break;
  90        case NLA_NESTED:
  91                /* a nested attributes is allowed to be empty; if its not,
  92                 * it must have a size of at least NLA_HDRLEN.
  93                 */
  94                if (attrlen == 0)
  95                        break;
  96        default:
  97                if (pt->len)
  98                        minlen = pt->len;
  99                else if (pt->type != NLA_UNSPEC)
 100                        minlen = nla_attr_minlen[pt->type];
 101
 102                if (attrlen < minlen)
 103                        return -ERANGE;
 104        }
 105
 106        return 0;
 107}
 108
 109/**
 110 * nla_validate - Validate a stream of attributes
 111 * @head: head of attribute stream
 112 * @len: length of attribute stream
 113 * @maxtype: maximum attribute type to be expected
 114 * @policy: validation policy
 115 *
 116 * Validates all attributes in the specified attribute stream against the
 117 * specified policy. Attributes with a type exceeding maxtype will be
 118 * ignored. See documenation of struct nla_policy for more details.
 119 *
 120 * Returns 0 on success or a negative error code.
 121 */
 122int nla_validate(const struct nlattr *head, int len, int maxtype,
 123                 const struct nla_policy *policy)
 124{
 125        const struct nlattr *nla;
 126        int rem, err;
 127
 128        nla_for_each_attr(nla, head, len, rem) {
 129                err = validate_nla(nla, maxtype, policy);
 130                if (err < 0)
 131                        goto errout;
 132        }
 133
 134        err = 0;
 135errout:
 136        return err;
 137}
 138EXPORT_SYMBOL(nla_validate);
 139
 140/**
 141 * nla_policy_len - Determin the max. length of a policy
 142 * @policy: policy to use
 143 * @n: number of policies
 144 *
 145 * Determines the max. length of the policy.  It is currently used
 146 * to allocated Netlink buffers roughly the size of the actual
 147 * message.
 148 *
 149 * Returns 0 on success or a negative error code.
 150 */
 151int
 152nla_policy_len(const struct nla_policy *p, int n)
 153{
 154        int i, len = 0;
 155
 156        for (i = 0; i < n; i++, p++) {
 157                if (p->len)
 158                        len += nla_total_size(p->len);
 159                else if (nla_attr_minlen[p->type])
 160                        len += nla_total_size(nla_attr_minlen[p->type]);
 161        }
 162
 163        return len;
 164}
 165EXPORT_SYMBOL(nla_policy_len);
 166
 167/**
 168 * nla_parse - Parse a stream of attributes into a tb buffer
 169 * @tb: destination array with maxtype+1 elements
 170 * @maxtype: maximum attribute type to be expected
 171 * @head: head of attribute stream
 172 * @len: length of attribute stream
 173 * @policy: validation policy
 174 *
 175 * Parses a stream of attributes and stores a pointer to each attribute in
 176 * the tb array accessible via the attribute type. Attributes with a type
 177 * exceeding maxtype will be silently ignored for backwards compatibility
 178 * reasons. policy may be set to NULL if no validation is required.
 179 *
 180 * Returns 0 on success or a negative error code.
 181 */
 182int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
 183              int len, const struct nla_policy *policy)
 184{
 185        const struct nlattr *nla;
 186        int rem, err;
 187
 188        memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
 189
 190        nla_for_each_attr(nla, head, len, rem) {
 191                u16 type = nla_type(nla);
 192
 193                if (type > 0 && type <= maxtype) {
 194                        if (policy) {
 195                                err = validate_nla(nla, maxtype, policy);
 196                                if (err < 0)
 197                                        goto errout;
 198                        }
 199
 200                        tb[type] = (struct nlattr *)nla;
 201                }
 202        }
 203
 204        if (unlikely(rem > 0))
 205                pr_warn_ratelimited("netlink: %d bytes leftover after parsing attributes in process `%s'.\n",
 206                                    rem, current->comm);
 207
 208        err = 0;
 209errout:
 210        return err;
 211}
 212EXPORT_SYMBOL(nla_parse);
 213
 214/**
 215 * nla_find - Find a specific attribute in a stream of attributes
 216 * @head: head of attribute stream
 217 * @len: length of attribute stream
 218 * @attrtype: type of attribute to look for
 219 *
 220 * Returns the first attribute in the stream matching the specified type.
 221 */
 222struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype)
 223{
 224        const struct nlattr *nla;
 225        int rem;
 226
 227        nla_for_each_attr(nla, head, len, rem)
 228                if (nla_type(nla) == attrtype)
 229                        return (struct nlattr *)nla;
 230
 231        return NULL;
 232}
 233EXPORT_SYMBOL(nla_find);
 234
 235/**
 236 * nla_strlcpy - Copy string attribute payload into a sized buffer
 237 * @dst: where to copy the string to
 238 * @nla: attribute to copy the string from
 239 * @dstsize: size of destination buffer
 240 *
 241 * Copies at most dstsize - 1 bytes into the destination buffer.
 242 * The result is always a valid NUL-terminated string. Unlike
 243 * strlcpy the destination buffer is always padded out.
 244 *
 245 * Returns the length of the source buffer.
 246 */
 247size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
 248{
 249        size_t srclen = nla_len(nla);
 250        char *src = nla_data(nla);
 251
 252        if (srclen > 0 && src[srclen - 1] == '\0')
 253                srclen--;
 254
 255        if (dstsize > 0) {
 256                size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
 257
 258                memset(dst, 0, dstsize);
 259                memcpy(dst, src, len);
 260        }
 261
 262        return srclen;
 263}
 264EXPORT_SYMBOL(nla_strlcpy);
 265
 266/**
 267 * nla_memcpy - Copy a netlink attribute into another memory area
 268 * @dest: where to copy to memcpy
 269 * @src: netlink attribute to copy from
 270 * @count: size of the destination area
 271 *
 272 * Note: The number of bytes copied is limited by the length of
 273 *       attribute's payload. memcpy
 274 *
 275 * Returns the number of bytes copied.
 276 */
 277int nla_memcpy(void *dest, const struct nlattr *src, int count)
 278{
 279        int minlen = min_t(int, count, nla_len(src));
 280
 281        memcpy(dest, nla_data(src), minlen);
 282        if (count > minlen)
 283                memset(dest + minlen, 0, count - minlen);
 284
 285        return minlen;
 286}
 287EXPORT_SYMBOL(nla_memcpy);
 288
 289/**
 290 * nla_memcmp - Compare an attribute with sized memory area
 291 * @nla: netlink attribute
 292 * @data: memory area
 293 * @size: size of memory area
 294 */
 295int nla_memcmp(const struct nlattr *nla, const void *data,
 296                             size_t size)
 297{
 298        int d = nla_len(nla) - size;
 299
 300        if (d == 0)
 301                d = memcmp(nla_data(nla), data, size);
 302
 303        return d;
 304}
 305EXPORT_SYMBOL(nla_memcmp);
 306
 307/**
 308 * nla_strcmp - Compare a string attribute against a string
 309 * @nla: netlink string attribute
 310 * @str: another string
 311 */
 312int nla_strcmp(const struct nlattr *nla, const char *str)
 313{
 314        int len = strlen(str);
 315        char *buf = nla_data(nla);
 316        int attrlen = nla_len(nla);
 317        int d;
 318
 319        if (attrlen > 0 && buf[attrlen - 1] == '\0')
 320                attrlen--;
 321
 322        d = attrlen - len;
 323        if (d == 0)
 324                d = memcmp(nla_data(nla), str, len);
 325
 326        return d;
 327}
 328EXPORT_SYMBOL(nla_strcmp);
 329
 330#ifdef CONFIG_NET
 331/**
 332 * __nla_reserve - reserve room for attribute on the skb
 333 * @skb: socket buffer to reserve room on
 334 * @attrtype: attribute type
 335 * @attrlen: length of attribute payload
 336 *
 337 * Adds a netlink attribute header to a socket buffer and reserves
 338 * room for the payload but does not copy it.
 339 *
 340 * The caller is responsible to ensure that the skb provides enough
 341 * tailroom for the attribute header and payload.
 342 */
 343struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
 344{
 345        struct nlattr *nla;
 346
 347        nla = (struct nlattr *) skb_put(skb, nla_total_size(attrlen));
 348        nla->nla_type = attrtype;
 349        nla->nla_len = nla_attr_size(attrlen);
 350
 351        memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
 352
 353        return nla;
 354}
 355EXPORT_SYMBOL(__nla_reserve);
 356
 357/**
 358 * __nla_reserve_nohdr - reserve room for attribute without header
 359 * @skb: socket buffer to reserve room on
 360 * @attrlen: length of attribute payload
 361 *
 362 * Reserves room for attribute payload without a header.
 363 *
 364 * The caller is responsible to ensure that the skb provides enough
 365 * tailroom for the payload.
 366 */
 367void *__nla_reserve_nohdr(struct sk_buff *skb, int attrlen)
 368{
 369        void *start;
 370
 371        start = skb_put(skb, NLA_ALIGN(attrlen));
 372        memset(start, 0, NLA_ALIGN(attrlen));
 373
 374        return start;
 375}
 376EXPORT_SYMBOL(__nla_reserve_nohdr);
 377
 378/**
 379 * nla_reserve - reserve room for attribute on the skb
 380 * @skb: socket buffer to reserve room on
 381 * @attrtype: attribute type
 382 * @attrlen: length of attribute payload
 383 *
 384 * Adds a netlink attribute header to a socket buffer and reserves
 385 * room for the payload but does not copy it.
 386 *
 387 * Returns NULL if the tailroom of the skb is insufficient to store
 388 * the attribute header and payload.
 389 */
 390struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
 391{
 392        if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
 393                return NULL;
 394
 395        return __nla_reserve(skb, attrtype, attrlen);
 396}
 397EXPORT_SYMBOL(nla_reserve);
 398
 399/**
 400 * nla_reserve_nohdr - reserve room for attribute without header
 401 * @skb: socket buffer to reserve room on
 402 * @attrlen: length of attribute payload
 403 *
 404 * Reserves room for attribute payload without a header.
 405 *
 406 * Returns NULL if the tailroom of the skb is insufficient to store
 407 * the attribute payload.
 408 */
 409void *nla_reserve_nohdr(struct sk_buff *skb, int attrlen)
 410{
 411        if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
 412                return NULL;
 413
 414        return __nla_reserve_nohdr(skb, attrlen);
 415}
 416EXPORT_SYMBOL(nla_reserve_nohdr);
 417
 418/**
 419 * __nla_put - Add a netlink attribute to a socket buffer
 420 * @skb: socket buffer to add attribute to
 421 * @attrtype: attribute type
 422 * @attrlen: length of attribute payload
 423 * @data: head of attribute payload
 424 *
 425 * The caller is responsible to ensure that the skb provides enough
 426 * tailroom for the attribute header and payload.
 427 */
 428void __nla_put(struct sk_buff *skb, int attrtype, int attrlen,
 429                             const void *data)
 430{
 431        struct nlattr *nla;
 432
 433        nla = __nla_reserve(skb, attrtype, attrlen);
 434        memcpy(nla_data(nla), data, attrlen);
 435}
 436EXPORT_SYMBOL(__nla_put);
 437
 438/**
 439 * __nla_put_nohdr - Add a netlink attribute without header
 440 * @skb: socket buffer to add attribute to
 441 * @attrlen: length of attribute payload
 442 * @data: head of attribute payload
 443 *
 444 * The caller is responsible to ensure that the skb provides enough
 445 * tailroom for the attribute payload.
 446 */
 447void __nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)
 448{
 449        void *start;
 450
 451        start = __nla_reserve_nohdr(skb, attrlen);
 452        memcpy(start, data, attrlen);
 453}
 454EXPORT_SYMBOL(__nla_put_nohdr);
 455
 456/**
 457 * nla_put - Add a netlink attribute to a socket buffer
 458 * @skb: socket buffer to add attribute to
 459 * @attrtype: attribute type
 460 * @attrlen: length of attribute payload
 461 * @data: head of attribute payload
 462 *
 463 * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store
 464 * the attribute header and payload.
 465 */
 466int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
 467{
 468        if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
 469                return -EMSGSIZE;
 470
 471        __nla_put(skb, attrtype, attrlen, data);
 472        return 0;
 473}
 474EXPORT_SYMBOL(nla_put);
 475
 476/**
 477 * nla_put_nohdr - Add a netlink attribute without header
 478 * @skb: socket buffer to add attribute to
 479 * @attrlen: length of attribute payload
 480 * @data: head of attribute payload
 481 *
 482 * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store
 483 * the attribute payload.
 484 */
 485int nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)
 486{
 487        if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
 488                return -EMSGSIZE;
 489
 490        __nla_put_nohdr(skb, attrlen, data);
 491        return 0;
 492}
 493EXPORT_SYMBOL(nla_put_nohdr);
 494
 495/**
 496 * nla_append - Add a netlink attribute without header or padding
 497 * @skb: socket buffer to add attribute to
 498 * @attrlen: length of attribute payload
 499 * @data: head of attribute payload
 500 *
 501 * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store
 502 * the attribute payload.
 503 */
 504int nla_append(struct sk_buff *skb, int attrlen, const void *data)
 505{
 506        if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
 507                return -EMSGSIZE;
 508
 509        memcpy(skb_put(skb, attrlen), data, attrlen);
 510        return 0;
 511}
 512EXPORT_SYMBOL(nla_append);
 513#endif
 514