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 @@  #include <linux/types.h>  #include <net/netlink.h> -/* for these data types attribute length must be exactly given size */ +/* For these data types, attribute length should be exactly the given + * size. However, to maintain compatibility with broken commands, if the + * attribute length does not match the expected size a warning is emitted + * to the user that the command is sending invalid data and needs to be fixed. + */  static const u8 nla_attr_len[NLA_TYPE_MAX+1] = {  	[NLA_U8]	= sizeof(u8),  	[NLA_U16]	= sizeof(u16), @@ -28,8 +32,16 @@ static const u8 nla_attr_len[NLA_TYPE_MAX+1] = {  };  static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = { +	[NLA_U8]	= sizeof(u8), +	[NLA_U16]	= sizeof(u16), +	[NLA_U32]	= sizeof(u32), +	[NLA_U64]	= sizeof(u64),  	[NLA_MSECS]	= sizeof(u64),  	[NLA_NESTED]	= NLA_HDRLEN, +	[NLA_S8]	= sizeof(s8), +	[NLA_S16]	= sizeof(s16), +	[NLA_S32]	= sizeof(s32), +	[NLA_S64]	= sizeof(s64),  };  static int validate_nla_bitfield32(const struct nlattr *nla, @@ -69,11 +81,9 @@ static int validate_nla(const struct nlattr *nla, int maxtype,  	BUG_ON(pt->type > NLA_TYPE_MAX); -	/* for data types NLA_U* and NLA_S* require exact length */ -	if (nla_attr_len[pt->type]) { -		if (attrlen != nla_attr_len[pt->type]) -			return -ERANGE; -		return 0; +	if (nla_attr_len[pt->type] && attrlen != nla_attr_len[pt->type]) { +		pr_warn_ratelimited("netlink: '%s': attribute type %d has an invalid length.\n", +				    current->comm, type);  	}  	switch (pt->type) {  | 
