diff options
Diffstat (limited to 'lib/nlattr.c')
-rw-r--r-- | lib/nlattr.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/lib/nlattr.c b/lib/nlattr.c index 8bf78b4b78f0..dfa55c873c13 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c | |||
@@ -15,7 +15,11 @@ | |||
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <net/netlink.h> | 16 | #include <net/netlink.h> |
17 | 17 | ||
18 | /* for these data types attribute length must be exactly given size */ | 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 | */ | ||
19 | static const u8 nla_attr_len[NLA_TYPE_MAX+1] = { | 23 | static const u8 nla_attr_len[NLA_TYPE_MAX+1] = { |
20 | [NLA_U8] = sizeof(u8), | 24 | [NLA_U8] = sizeof(u8), |
21 | [NLA_U16] = sizeof(u16), | 25 | [NLA_U16] = sizeof(u16), |
@@ -28,8 +32,16 @@ static const u8 nla_attr_len[NLA_TYPE_MAX+1] = { | |||
28 | }; | 32 | }; |
29 | 33 | ||
30 | static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = { | 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), | ||
31 | [NLA_MSECS] = sizeof(u64), | 39 | [NLA_MSECS] = sizeof(u64), |
32 | [NLA_NESTED] = NLA_HDRLEN, | 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), | ||
33 | }; | 45 | }; |
34 | 46 | ||
35 | static int validate_nla_bitfield32(const struct nlattr *nla, | 47 | static int validate_nla_bitfield32(const struct nlattr *nla, |
@@ -69,11 +81,9 @@ static int validate_nla(const struct nlattr *nla, int maxtype, | |||
69 | 81 | ||
70 | BUG_ON(pt->type > NLA_TYPE_MAX); | 82 | BUG_ON(pt->type > NLA_TYPE_MAX); |
71 | 83 | ||
72 | /* for data types NLA_U* and NLA_S* require exact length */ | 84 | if (nla_attr_len[pt->type] && attrlen != nla_attr_len[pt->type]) { |
73 | if (nla_attr_len[pt->type]) { | 85 | pr_warn_ratelimited("netlink: '%s': attribute type %d has an invalid length.\n", |
74 | if (attrlen != nla_attr_len[pt->type]) | 86 | current->comm, type); |
75 | return -ERANGE; | ||
76 | return 0; | ||
77 | } | 87 | } |
78 | 88 | ||
79 | switch (pt->type) { | 89 | switch (pt->type) { |