Skip to content

Commit 6fe8d3c

Browse files
n132gregkh
authored andcommitted
netfilter: ebtables: terminate table name before find_table_lock()
commit a622d2e upstream. update_counters() and compat_update_counters() forward a user-supplied 32-byte table name to find_table_lock() without NUL-terminating it. On a lookup miss, find_inlist_lock() calls try_then_request_module(..., "%s%s", "ebtable_", name), and vsnprintf() reads past the name field and the stack object until it hits a zero byte. BUG: KASAN: stack-out-of-bounds in string (lib/vsprintf.c:648 lib/vsprintf.c:730) Read of size 1 at addr ffff8880119dfb20 by task exploit/147 Call Trace: ... string (lib/vsprintf.c:648 lib/vsprintf.c:730) vsnprintf (lib/vsprintf.c:2945) __request_module (kernel/module/kmod.c:150) do_update_counters.isra.0 (net/bridge/netfilter/ebtables.c:371 net/bridge/netfilter/ebtables.c:380) update_counters (net/bridge/netfilter/ebtables.c:1440) do_ebt_set_ctl (net/bridge/netfilter/ebtables.c:2573) nf_setsockopt (net/netfilter/nf_sockopt.c:101) ip_setsockopt (net/ipv4/ip_sockglue.c:1424) raw_setsockopt (net/ipv4/raw.c:847) __sys_setsockopt (net/socket.c:2393) ... compat_do_replace() shares the same unterminated name via compat_copy_ebt_replace_from_user(); terminate it there too so all find_table_lock() callers behave alike. The other callers already terminate the name after the copy. Fixes: 1da177e ("Linux-2.6.12-rc2") Fixes: 81e675c ("netfilter: ebtables: add CONFIG_COMPAT support") Cc: stable@vger.kernel.org Reported-by: Weiming Shi <bestswngs@gmail.com> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Xiang Mei <xmei5@asu.edu> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 13a5f53 commit 6fe8d3c

1 file changed

Lines changed: 6 additions & 0 deletions

File tree

net/bridge/netfilter/ebtables.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,8 @@ static int update_counters(struct net *net, sockptr_t arg, unsigned int len)
14361436
if (copy_from_sockptr(&hlp, arg, sizeof(hlp)))
14371437
return -EFAULT;
14381438

1439+
hlp.name[sizeof(hlp.name) - 1] = '\0';
1440+
14391441
if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
14401442
return -EINVAL;
14411443

@@ -2275,6 +2277,8 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
22752277

22762278
memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));
22772279

2280+
repl->name[sizeof(repl->name) - 1] = '\0';
2281+
22782282
/* starting with hook_entry, 32 vs. 64 bit structures are different */
22792283
for (i = 0; i < NF_BR_NUMHOOKS; i++)
22802284
repl->hook_entry[i] = compat_ptr(tmp.hook_entry[i]);
@@ -2397,6 +2401,8 @@ static int compat_update_counters(struct net *net, sockptr_t arg,
23972401
if (copy_from_sockptr(&hlp, arg, sizeof(hlp)))
23982402
return -EFAULT;
23992403

2404+
hlp.name[sizeof(hlp.name) - 1] = '\0';
2405+
24002406
/* try real handler in case userland supplied needed padding */
24012407
if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
24022408
return update_counters(net, arg, len);

0 commit comments

Comments
 (0)