mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net: netlink: Update attr validation to require exact length for some types
Attributes using NLA_U* and NLA_S* (where * is 8, 16,32 and 64) are expected to be an exact length. Split these data types from nla_attr_minlen into nla_attr_len and update validate_nla to require the attribute to have exact length for them. Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									2210d6b2f2
								
							
						
					
					
						commit
						28033ae4e0
					
				
					 1 changed files with 16 additions and 3 deletions
				
			
		
							
								
								
									
										19
									
								
								lib/nlattr.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								lib/nlattr.c
									
									
									
									
									
								
							| 
						 | 
					@ -15,19 +15,23 @@
 | 
				
			||||||
#include <linux/types.h>
 | 
					#include <linux/types.h>
 | 
				
			||||||
#include <net/netlink.h>
 | 
					#include <net/netlink.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = {
 | 
					/* for these data types attribute length must be exactly given size */
 | 
				
			||||||
 | 
					static const u8 nla_attr_len[NLA_TYPE_MAX+1] = {
 | 
				
			||||||
	[NLA_U8]	= sizeof(u8),
 | 
						[NLA_U8]	= sizeof(u8),
 | 
				
			||||||
	[NLA_U16]	= sizeof(u16),
 | 
						[NLA_U16]	= sizeof(u16),
 | 
				
			||||||
	[NLA_U32]	= sizeof(u32),
 | 
						[NLA_U32]	= sizeof(u32),
 | 
				
			||||||
	[NLA_U64]	= sizeof(u64),
 | 
						[NLA_U64]	= sizeof(u64),
 | 
				
			||||||
	[NLA_MSECS]	= sizeof(u64),
 | 
					 | 
				
			||||||
	[NLA_NESTED]	= NLA_HDRLEN,
 | 
					 | 
				
			||||||
	[NLA_S8]	= sizeof(s8),
 | 
						[NLA_S8]	= sizeof(s8),
 | 
				
			||||||
	[NLA_S16]	= sizeof(s16),
 | 
						[NLA_S16]	= sizeof(s16),
 | 
				
			||||||
	[NLA_S32]	= sizeof(s32),
 | 
						[NLA_S32]	= sizeof(s32),
 | 
				
			||||||
	[NLA_S64]	= sizeof(s64),
 | 
						[NLA_S64]	= sizeof(s64),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = {
 | 
				
			||||||
 | 
						[NLA_MSECS]	= sizeof(u64),
 | 
				
			||||||
 | 
						[NLA_NESTED]	= NLA_HDRLEN,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int validate_nla_bitfield32(const struct nlattr *nla,
 | 
					static int validate_nla_bitfield32(const struct nlattr *nla,
 | 
				
			||||||
				   u32 *valid_flags_allowed)
 | 
									   u32 *valid_flags_allowed)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -65,6 +69,13 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUG_ON(pt->type > NLA_TYPE_MAX);
 | 
						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;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (pt->type) {
 | 
						switch (pt->type) {
 | 
				
			||||||
	case NLA_FLAG:
 | 
						case NLA_FLAG:
 | 
				
			||||||
		if (attrlen > 0)
 | 
							if (attrlen > 0)
 | 
				
			||||||
| 
						 | 
					@ -191,6 +202,8 @@ nla_policy_len(const struct nla_policy *p, int n)
 | 
				
			||||||
	for (i = 0; i < n; i++, p++) {
 | 
						for (i = 0; i < n; i++, p++) {
 | 
				
			||||||
		if (p->len)
 | 
							if (p->len)
 | 
				
			||||||
			len += nla_total_size(p->len);
 | 
								len += nla_total_size(p->len);
 | 
				
			||||||
 | 
							else if (nla_attr_len[p->type])
 | 
				
			||||||
 | 
								len += nla_total_size(nla_attr_len[p->type]);
 | 
				
			||||||
		else if (nla_attr_minlen[p->type])
 | 
							else if (nla_attr_minlen[p->type])
 | 
				
			||||||
			len += nla_total_size(nla_attr_minlen[p->type]);
 | 
								len += nla_total_size(nla_attr_minlen[p->type]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue