Skip to content

Commit 2664f53

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 d2367d9 commit 2664f53

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
@@ -1433,6 +1433,8 @@ static int update_counters(struct net *net, sockptr_t arg, unsigned int len)
14331433
if (copy_from_sockptr(&hlp, arg, sizeof(hlp)))
14341434
return -EFAULT;
14351435

1436+
hlp.name[sizeof(hlp.name) - 1] = '\0';
1437+
14361438
if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
14371439
return -EINVAL;
14381440

@@ -2272,6 +2274,8 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
22722274

22732275
memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));
22742276

2277+
repl->name[sizeof(repl->name) - 1] = '\0';
2278+
22752279
/* starting with hook_entry, 32 vs. 64 bit structures are different */
22762280
for (i = 0; i < NF_BR_NUMHOOKS; i++)
22772281
repl->hook_entry[i] = compat_ptr(tmp.hook_entry[i]);
@@ -2394,6 +2398,8 @@ static int compat_update_counters(struct net *net, sockptr_t arg,
23942398
if (copy_from_sockptr(&hlp, arg, sizeof(hlp)))
23952399
return -EFAULT;
23962400

2401+
hlp.name[sizeof(hlp.name) - 1] = '\0';
2402+
23972403
/* try real handler in case userland supplied needed padding */
23982404
if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
23992405
return update_counters(net, arg, len);

0 commit comments

Comments
 (0)