Skip to content

Commit 65acf6e

Browse files
edumazetkuba-moo
authored andcommitted
netfilter: complete validation of user input
In my recent commit, I missed that do_replace() handlers use copy_from_sockptr() (which I fixed), followed by unsafe copy_from_sockptr_offset() calls. In all functions, we can perform the @optlen validation before even calling xt_alloc_table_info() with the following check: if ((u64)optlen < (u64)tmp.size + sizeof(tmp)) return -EINVAL; Fixes: 0c83842 ("netfilter: validate user input for expected length") Reported-by: syzbot <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: Pablo Neira Ayuso <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 97e176f commit 65acf6e

File tree

3 files changed

+12
-0
lines changed

3 files changed

+12
-0
lines changed

net/ipv4/netfilter/arp_tables.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,8 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
966966
return -ENOMEM;
967967
if (tmp.num_counters == 0)
968968
return -EINVAL;
969+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
970+
return -EINVAL;
969971

970972
tmp.name[sizeof(tmp.name)-1] = 0;
971973

@@ -1266,6 +1268,8 @@ static int compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
12661268
return -ENOMEM;
12671269
if (tmp.num_counters == 0)
12681270
return -EINVAL;
1271+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
1272+
return -EINVAL;
12691273

12701274
tmp.name[sizeof(tmp.name)-1] = 0;
12711275

net/ipv4/netfilter/ip_tables.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,8 @@ do_replace(struct net *net, sockptr_t arg, unsigned int len)
11181118
return -ENOMEM;
11191119
if (tmp.num_counters == 0)
11201120
return -EINVAL;
1121+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
1122+
return -EINVAL;
11211123

11221124
tmp.name[sizeof(tmp.name)-1] = 0;
11231125

@@ -1504,6 +1506,8 @@ compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
15041506
return -ENOMEM;
15051507
if (tmp.num_counters == 0)
15061508
return -EINVAL;
1509+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
1510+
return -EINVAL;
15071511

15081512
tmp.name[sizeof(tmp.name)-1] = 0;
15091513

net/ipv6/netfilter/ip6_tables.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,8 @@ do_replace(struct net *net, sockptr_t arg, unsigned int len)
11351135
return -ENOMEM;
11361136
if (tmp.num_counters == 0)
11371137
return -EINVAL;
1138+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
1139+
return -EINVAL;
11381140

11391141
tmp.name[sizeof(tmp.name)-1] = 0;
11401142

@@ -1513,6 +1515,8 @@ compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
15131515
return -ENOMEM;
15141516
if (tmp.num_counters == 0)
15151517
return -EINVAL;
1518+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
1519+
return -EINVAL;
15161520

15171521
tmp.name[sizeof(tmp.name)-1] = 0;
15181522

0 commit comments

Comments
 (0)