Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: fix wrong arithmetics regarding NFT_REJECT_ICMPX_MAX

NFT_REJECT_ICMPX_MAX should be __NFT_REJECT_ICMPX_MAX - 1.

nft_reject_icmp_code() and nft_reject_icmpv6_code() are called from the
packet path, so BUG_ON in case we try to access an unknown abstracted
ICMP code. This should not happen since we already validate this from
nft_reject_{inet,bridge}_init().

Fixes: 51b0a5d ("netfilter: nft_reject: introduce icmp code abstraction for inet and bridge")
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

+5 -7
+1 -1
include/uapi/linux/netfilter/nf_tables.h
··· 774 774 NFT_REJECT_ICMPX_ADMIN_PROHIBITED, 775 775 __NFT_REJECT_ICMPX_MAX 776 776 }; 777 - #define NFT_REJECT_ICMPX_MAX (__NFT_REJECT_ICMPX_MAX + 1) 777 + #define NFT_REJECT_ICMPX_MAX (__NFT_REJECT_ICMPX_MAX - 1) 778 778 779 779 /** 780 780 * enum nft_reject_attributes - nf_tables reject expression netlink attributes
+4 -6
net/netfilter/nft_reject.c
··· 72 72 } 73 73 EXPORT_SYMBOL_GPL(nft_reject_dump); 74 74 75 - static u8 icmp_code_v4[NFT_REJECT_ICMPX_MAX] = { 75 + static u8 icmp_code_v4[NFT_REJECT_ICMPX_MAX + 1] = { 76 76 [NFT_REJECT_ICMPX_NO_ROUTE] = ICMP_NET_UNREACH, 77 77 [NFT_REJECT_ICMPX_PORT_UNREACH] = ICMP_PORT_UNREACH, 78 78 [NFT_REJECT_ICMPX_HOST_UNREACH] = ICMP_HOST_UNREACH, ··· 81 81 82 82 int nft_reject_icmp_code(u8 code) 83 83 { 84 - if (code > NFT_REJECT_ICMPX_MAX) 85 - return -EINVAL; 84 + BUG_ON(code > NFT_REJECT_ICMPX_MAX); 86 85 87 86 return icmp_code_v4[code]; 88 87 } ··· 89 90 EXPORT_SYMBOL_GPL(nft_reject_icmp_code); 90 91 91 92 92 - static u8 icmp_code_v6[NFT_REJECT_ICMPX_MAX] = { 93 + static u8 icmp_code_v6[NFT_REJECT_ICMPX_MAX + 1] = { 93 94 [NFT_REJECT_ICMPX_NO_ROUTE] = ICMPV6_NOROUTE, 94 95 [NFT_REJECT_ICMPX_PORT_UNREACH] = ICMPV6_PORT_UNREACH, 95 96 [NFT_REJECT_ICMPX_HOST_UNREACH] = ICMPV6_ADDR_UNREACH, ··· 98 99 99 100 int nft_reject_icmpv6_code(u8 code) 100 101 { 101 - if (code > NFT_REJECT_ICMPX_MAX) 102 - return -EINVAL; 102 + BUG_ON(code > NFT_REJECT_ICMPX_MAX); 103 103 104 104 return icmp_code_v6[code]; 105 105 }