Skip to content

Commit 4473236

Browse files
committed
netfilter: complete validation of user input
jira VULN-5223 cve CVE-2024-35962 commit-author Eric Dumazet <[email protected]> commit 65acf6e 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]> (cherry picked from commit 65acf6e) Signed-off-by: Brett Mastbergen <[email protected]>
1 parent 4d08a48 commit 4473236

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
@@ -965,6 +965,8 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
965965
return -ENOMEM;
966966
if (tmp.num_counters == 0)
967967
return -EINVAL;
968+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
969+
return -EINVAL;
968970

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

@@ -1265,6 +1267,8 @@ static int compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
12651267
return -ENOMEM;
12661268
if (tmp.num_counters == 0)
12671269
return -EINVAL;
1270+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
1271+
return -EINVAL;
12681272

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

net/ipv4/netfilter/ip_tables.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,8 @@ do_replace(struct net *net, sockptr_t arg, unsigned int len)
11201120
return -ENOMEM;
11211121
if (tmp.num_counters == 0)
11221122
return -EINVAL;
1123+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
1124+
return -EINVAL;
11231125

11241126
tmp.name[sizeof(tmp.name)-1] = 0;
11251127

@@ -1506,6 +1508,8 @@ compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
15061508
return -ENOMEM;
15071509
if (tmp.num_counters == 0)
15081510
return -EINVAL;
1511+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
1512+
return -EINVAL;
15091513

15101514
tmp.name[sizeof(tmp.name)-1] = 0;
15111515

net/ipv6/netfilter/ip6_tables.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,8 @@ do_replace(struct net *net, sockptr_t arg, unsigned int len)
11371137
return -ENOMEM;
11381138
if (tmp.num_counters == 0)
11391139
return -EINVAL;
1140+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
1141+
return -EINVAL;
11401142

11411143
tmp.name[sizeof(tmp.name)-1] = 0;
11421144

@@ -1515,6 +1517,8 @@ compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)
15151517
return -ENOMEM;
15161518
if (tmp.num_counters == 0)
15171519
return -EINVAL;
1520+
if ((u64)len < (u64)tmp.size + sizeof(tmp))
1521+
return -EINVAL;
15181522

15191523
tmp.name[sizeof(tmp.name)-1] = 0;
15201524

0 commit comments

Comments
 (0)