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