Skip to content

Commit 260466b

Browse files
edumazetkuba-moo
authored andcommitted
ila: serialize calls to nf_register_net_hooks()
syzbot found a race in ila_add_mapping() [1] commit 031ae72 ("ila: call nf_unregister_net_hooks() sooner") attempted to fix a similar issue. Looking at the syzbot repro, we have concurrent ILA_CMD_ADD commands. Add a mutex to make sure at most one thread is calling nf_register_net_hooks(). [1] BUG: KASAN: slab-use-after-free in rht_key_hashfn include/linux/rhashtable.h:159 [inline] BUG: KASAN: slab-use-after-free in __rhashtable_lookup.constprop.0+0x426/0x550 include/linux/rhashtable.h:604 Read of size 4 at addr ffff888028f40008 by task dhcpcd/5501 CPU: 1 UID: 0 PID: 5501 Comm: dhcpcd Not tainted 6.13.0-rc4-syzkaller-00054-gd6ef8b40d075 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 Call Trace: <IRQ> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0xc3/0x620 mm/kasan/report.c:489 kasan_report+0xd9/0x110 mm/kasan/report.c:602 rht_key_hashfn include/linux/rhashtable.h:159 [inline] __rhashtable_lookup.constprop.0+0x426/0x550 include/linux/rhashtable.h:604 rhashtable_lookup include/linux/rhashtable.h:646 [inline] rhashtable_lookup_fast include/linux/rhashtable.h:672 [inline] ila_lookup_wildcards net/ipv6/ila/ila_xlat.c:127 [inline] ila_xlat_addr net/ipv6/ila/ila_xlat.c:652 [inline] ila_nf_input+0x1ee/0x620 net/ipv6/ila/ila_xlat.c:185 nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline] nf_hook_slow+0xbb/0x200 net/netfilter/core.c:626 nf_hook.constprop.0+0x42e/0x750 include/linux/netfilter.h:269 NF_HOOK include/linux/netfilter.h:312 [inline] ipv6_rcv+0xa4/0x680 net/ipv6/ip6_input.c:309 __netif_receive_skb_one_core+0x12e/0x1e0 net/core/dev.c:5672 __netif_receive_skb+0x1d/0x160 net/core/dev.c:5785 process_backlog+0x443/0x15f0 net/core/dev.c:6117 __napi_poll.constprop.0+0xb7/0x550 net/core/dev.c:6883 napi_poll net/core/dev.c:6952 [inline] net_rx_action+0xa94/0x1010 net/core/dev.c:7074 handle_softirqs+0x213/0x8f0 kernel/softirq.c:561 __do_softirq kernel/softirq.c:595 [inline] invoke_softirq kernel/softirq.c:435 [inline] __irq_exit_rcu+0x109/0x170 kernel/softirq.c:662 irq_exit_rcu+0x9/0x30 kernel/softirq.c:678 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1049 [inline] sysvec_apic_timer_interrupt+0xa4/0xc0 arch/x86/kernel/apic/apic.c:1049 Fixes: 7f00fea ("ila: Add generic ILA translation facility") Reported-by: syzbot+47e761d22ecf745f72b9@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6772c9ae.050a0220.2f3838.04c7.GAE@google.com/T/#u Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Florian Westphal <fw@strlen.de> Cc: Tom Herbert <tom@herbertland.com> Link: https://patch.msgid.link/20241230162849.2795486-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent f91a5b8 commit 260466b

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

net/ipv6/ila/ila_xlat.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,23 +195,29 @@ static const struct nf_hook_ops ila_nf_hook_ops[] = {
195195
},
196196
};
197197

198+
static DEFINE_MUTEX(ila_mutex);
199+
198200
static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp)
199201
{
200202
struct ila_net *ilan = net_generic(net, ila_net_id);
201203
struct ila_map *ila, *head;
202204
spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match);
203205
int err = 0, order;
204206

205-
if (!ilan->xlat.hooks_registered) {
207+
if (!READ_ONCE(ilan->xlat.hooks_registered)) {
206208
/* We defer registering net hooks in the namespace until the
207209
* first mapping is added.
208210
*/
209-
err = nf_register_net_hooks(net, ila_nf_hook_ops,
210-
ARRAY_SIZE(ila_nf_hook_ops));
211+
mutex_lock(&ila_mutex);
212+
if (!ilan->xlat.hooks_registered) {
213+
err = nf_register_net_hooks(net, ila_nf_hook_ops,
214+
ARRAY_SIZE(ila_nf_hook_ops));
215+
if (!err)
216+
WRITE_ONCE(ilan->xlat.hooks_registered, true);
217+
}
218+
mutex_unlock(&ila_mutex);
211219
if (err)
212220
return err;
213-
214-
ilan->xlat.hooks_registered = true;
215221
}
216222

217223
ila = kzalloc(sizeof(*ila), GFP_KERNEL);

0 commit comments

Comments
 (0)