mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	netlink: introduce bigendian integer types
Jakub reported that the addition of the "network_byte_order"
member in struct nla_policy increases size of 32bit platforms.
Instead of scraping the bit from elsewhere Johannes suggested
to add explicit NLA_BE types instead, so do this here.
NLA_POLICY_MAX_BE() macro is removed again, there is no need
for it: NLA_POLICY_MAX(NLA_BE.., ..) will do the right thing.
NLA_BE64 can be added later.
Fixes: 08724ef699 ("netlink: introduce NLA_POLICY_MAX_BE")
Reported-by: Jakub Kicinski <kuba@kernel.org>
Suggested-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
Link: https://lore.kernel.org/r/20221031123407.9158-1-fw@strlen.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									fc57062f98
								
							
						
					
					
						commit
						ecaf75ffd5
					
				
					 3 changed files with 28 additions and 38 deletions
				
			
		|  | @ -181,6 +181,8 @@ enum { | |||
| 	NLA_S64, | ||||
| 	NLA_BITFIELD32, | ||||
| 	NLA_REJECT, | ||||
| 	NLA_BE16, | ||||
| 	NLA_BE32, | ||||
| 	__NLA_TYPE_MAX, | ||||
| }; | ||||
| 
 | ||||
|  | @ -231,6 +233,7 @@ enum nla_policy_validation { | |||
|  *    NLA_U32, NLA_U64, | ||||
|  *    NLA_S8, NLA_S16, | ||||
|  *    NLA_S32, NLA_S64, | ||||
|  *    NLA_BE16, NLA_BE32, | ||||
|  *    NLA_MSECS            Leaving the length field zero will verify the | ||||
|  *                         given type fits, using it verifies minimum length | ||||
|  *                         just like "All other" | ||||
|  | @ -261,6 +264,8 @@ enum nla_policy_validation { | |||
|  *    NLA_U16, | ||||
|  *    NLA_U32, | ||||
|  *    NLA_U64, | ||||
|  *    NLA_BE16, | ||||
|  *    NLA_BE32, | ||||
|  *    NLA_S8, | ||||
|  *    NLA_S16, | ||||
|  *    NLA_S32, | ||||
|  | @ -349,7 +354,6 @@ struct nla_policy { | |||
| 		struct netlink_range_validation_signed *range_signed; | ||||
| 		struct { | ||||
| 			s16 min, max; | ||||
| 			u8 network_byte_order:1; | ||||
| 		}; | ||||
| 		int (*validate)(const struct nlattr *attr, | ||||
| 				struct netlink_ext_ack *extack); | ||||
|  | @ -374,6 +378,8 @@ struct nla_policy { | |||
| 	(tp == NLA_U8 || tp == NLA_U16 || tp == NLA_U32 || tp == NLA_U64) | ||||
| #define __NLA_IS_SINT_TYPE(tp)						\ | ||||
| 	(tp == NLA_S8 || tp == NLA_S16 || tp == NLA_S32 || tp == NLA_S64) | ||||
| #define __NLA_IS_BEINT_TYPE(tp)						\ | ||||
| 	(tp == NLA_BE16 || tp == NLA_BE32) | ||||
| 
 | ||||
| #define __NLA_ENSURE(condition) BUILD_BUG_ON_ZERO(!(condition)) | ||||
| #define NLA_ENSURE_UINT_TYPE(tp)			\ | ||||
|  | @ -387,6 +393,7 @@ struct nla_policy { | |||
| #define NLA_ENSURE_INT_OR_BINARY_TYPE(tp)		\ | ||||
| 	(__NLA_ENSURE(__NLA_IS_UINT_TYPE(tp) ||		\ | ||||
| 		      __NLA_IS_SINT_TYPE(tp) ||		\ | ||||
| 		      __NLA_IS_BEINT_TYPE(tp) ||	\ | ||||
| 		      tp == NLA_MSECS ||		\ | ||||
| 		      tp == NLA_BINARY) + tp) | ||||
| #define NLA_ENSURE_NO_VALIDATION_PTR(tp)		\ | ||||
|  | @ -394,6 +401,8 @@ struct nla_policy { | |||
| 		      tp != NLA_REJECT &&		\ | ||||
| 		      tp != NLA_NESTED &&		\ | ||||
| 		      tp != NLA_NESTED_ARRAY) + tp) | ||||
| #define NLA_ENSURE_BEINT_TYPE(tp)			\ | ||||
| 	(__NLA_ENSURE(__NLA_IS_BEINT_TYPE(tp)) + tp) | ||||
| 
 | ||||
| #define NLA_POLICY_RANGE(tp, _min, _max) {		\ | ||||
| 	.type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp),	\ | ||||
|  | @ -424,14 +433,6 @@ struct nla_policy { | |||
| 	.type = NLA_ENSURE_INT_OR_BINARY_TYPE(tp),	\ | ||||
| 	.validation_type = NLA_VALIDATE_MAX,		\ | ||||
| 	.max = _max,					\ | ||||
| 	.network_byte_order = 0,			\ | ||||
| } | ||||
| 
 | ||||
| #define NLA_POLICY_MAX_BE(tp, _max) {			\ | ||||
| 	.type = NLA_ENSURE_UINT_TYPE(tp),		\ | ||||
| 	.validation_type = NLA_VALIDATE_MAX,		\ | ||||
| 	.max = _max,					\ | ||||
| 	.network_byte_order = 1,			\ | ||||
| } | ||||
| 
 | ||||
| #define NLA_POLICY_MASK(tp, _mask) {			\ | ||||
|  |  | |||
							
								
								
									
										41
									
								
								lib/nlattr.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								lib/nlattr.c
									
									
									
									
									
								
							|  | @ -124,10 +124,12 @@ void nla_get_range_unsigned(const struct nla_policy *pt, | |||
| 		range->max = U8_MAX; | ||||
| 		break; | ||||
| 	case NLA_U16: | ||||
| 	case NLA_BE16: | ||||
| 	case NLA_BINARY: | ||||
| 		range->max = U16_MAX; | ||||
| 		break; | ||||
| 	case NLA_U32: | ||||
| 	case NLA_BE32: | ||||
| 		range->max = U32_MAX; | ||||
| 		break; | ||||
| 	case NLA_U64: | ||||
|  | @ -159,31 +161,6 @@ void nla_get_range_unsigned(const struct nla_policy *pt, | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static u64 nla_get_attr_bo(const struct nla_policy *pt, | ||||
| 			   const struct nlattr *nla) | ||||
| { | ||||
| 	switch (pt->type) { | ||||
| 	case NLA_U16: | ||||
| 		if (pt->network_byte_order) | ||||
| 			return ntohs(nla_get_be16(nla)); | ||||
| 
 | ||||
| 		return nla_get_u16(nla); | ||||
| 	case NLA_U32: | ||||
| 		if (pt->network_byte_order) | ||||
| 			return ntohl(nla_get_be32(nla)); | ||||
| 
 | ||||
| 		return nla_get_u32(nla); | ||||
| 	case NLA_U64: | ||||
| 		if (pt->network_byte_order) | ||||
| 			return be64_to_cpu(nla_get_be64(nla)); | ||||
| 
 | ||||
| 		return nla_get_u64(nla); | ||||
| 	} | ||||
| 
 | ||||
| 	WARN_ON_ONCE(1); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int nla_validate_range_unsigned(const struct nla_policy *pt, | ||||
| 				       const struct nlattr *nla, | ||||
| 				       struct netlink_ext_ack *extack, | ||||
|  | @ -197,9 +174,13 @@ static int nla_validate_range_unsigned(const struct nla_policy *pt, | |||
| 		value = nla_get_u8(nla); | ||||
| 		break; | ||||
| 	case NLA_U16: | ||||
| 		value = nla_get_u16(nla); | ||||
| 		break; | ||||
| 	case NLA_U32: | ||||
| 		value = nla_get_u32(nla); | ||||
| 		break; | ||||
| 	case NLA_U64: | ||||
| 		value = nla_get_attr_bo(pt, nla); | ||||
| 		value = nla_get_u64(nla); | ||||
| 		break; | ||||
| 	case NLA_MSECS: | ||||
| 		value = nla_get_u64(nla); | ||||
|  | @ -207,6 +188,12 @@ static int nla_validate_range_unsigned(const struct nla_policy *pt, | |||
| 	case NLA_BINARY: | ||||
| 		value = nla_len(nla); | ||||
| 		break; | ||||
| 	case NLA_BE16: | ||||
| 		value = ntohs(nla_get_be16(nla)); | ||||
| 		break; | ||||
| 	case NLA_BE32: | ||||
| 		value = ntohl(nla_get_be32(nla)); | ||||
| 		break; | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | @ -334,6 +321,8 @@ static int nla_validate_int_range(const struct nla_policy *pt, | |||
| 	case NLA_U64: | ||||
| 	case NLA_MSECS: | ||||
| 	case NLA_BINARY: | ||||
| 	case NLA_BE16: | ||||
| 	case NLA_BE32: | ||||
| 		return nla_validate_range_unsigned(pt, nla, extack, validate); | ||||
| 	case NLA_S8: | ||||
| 	case NLA_S16: | ||||
|  |  | |||
|  | @ -173,10 +173,10 @@ static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = { | |||
| 	[NFTA_PAYLOAD_SREG]		= { .type = NLA_U32 }, | ||||
| 	[NFTA_PAYLOAD_DREG]		= { .type = NLA_U32 }, | ||||
| 	[NFTA_PAYLOAD_BASE]		= { .type = NLA_U32 }, | ||||
| 	[NFTA_PAYLOAD_OFFSET]		= NLA_POLICY_MAX_BE(NLA_U32, 255), | ||||
| 	[NFTA_PAYLOAD_LEN]		= NLA_POLICY_MAX_BE(NLA_U32, 255), | ||||
| 	[NFTA_PAYLOAD_OFFSET]		= NLA_POLICY_MAX(NLA_BE32, 255), | ||||
| 	[NFTA_PAYLOAD_LEN]		= NLA_POLICY_MAX(NLA_BE32, 255), | ||||
| 	[NFTA_PAYLOAD_CSUM_TYPE]	= { .type = NLA_U32 }, | ||||
| 	[NFTA_PAYLOAD_CSUM_OFFSET]	= NLA_POLICY_MAX_BE(NLA_U32, 255), | ||||
| 	[NFTA_PAYLOAD_CSUM_OFFSET]	= NLA_POLICY_MAX(NLA_BE32, 255), | ||||
| 	[NFTA_PAYLOAD_CSUM_FLAGS]	= { .type = NLA_U32 }, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Florian Westphal
						Florian Westphal