ANDROID: fix KASAN-related kernel crash by KMI W/A for NETFILTER_FAMILY_BRIDGE
KASAN-related crash observed on aosp-main cuttlefish with commit b37eb452. In commit b37eb452 ("KMI workaround for CONFIG_NETFILTER_FAMILY_BRIDGE"), type struct nf_hook_entries for global init_net are statically preserved as 'init_nf_hooks_bridge' which is an array of type struct nf_hook_entries instead of a member of struct net_ns. And also 'init_nf_hooks_bridgep' addresses to init_nf_hooks_bridge. netfilter_net_init() initialize the pointer array of type struct nf_hook_entries but in case for nf_hook_birdge, get_nf_hooks_bridge() for init_net returns the address of 'init_nf_hooks_bridgep' that is compatible with type struct nf_hook_entries ** but it's not allocated array size of nf_hook_entries (NF_INET_NUMHOOKS) As the result, netfilter_net_init() initialize out-of-bounds memory and then it possibly causes kernel panic with KASAN enabled configuration. [ 15.437905] ================================================================== [ 15.439156] BUG: KASAN: global-out-of-bounds in netfilter_net_init+0x17b/0x240 [ 15.439156] Write of size 8 at addr ffffffff84e40488 by task swapper/0/1 [ 15.439156] [ 15.439156] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.15.137-android13-8-... [ 15.439156] Hardware name: emulation qemu-x86/qemu-x86, BIOS 2023.04-gc2f63... [ 15.439156] Call Trace: [ 15.439156] <TASK> [ 15.439156] dump_stack_lvl+0xbb/0xf2 [ 15.439156] print_address_description+0x87/0x3b0 [ 15.439156] ? _raw_spin_lock_irqsave+0x80/0xe0 [ 15.439156] kasan_report+0x17a/0x1c0 [ 15.439156] ? netfilter_net_init+0x17b/0x240 [ 15.439156] ? netfilter_net_init+0x17b/0x240 [ 15.439156] __asan_store8+0x80/0x90 [ 15.439156] netfilter_net_init+0x17b/0x240 [ 15.439156] ops_init+0x1dd/0x290 [ 15.439156] ? kfree+0xc8/0x210 [ 15.439156] register_pernet_operations+0x176/0x350 [ 15.439156] ? alsa_sound_last_init+0x97/0x97 [ 15.439156] register_pernet_subsys+0x28/0x40 [ 15.439156] netfilter_init+0x16/0x4d [ 15.439156] sock_init+0xa1/0xc6 [ 15.439156] do_one_initcall+0xfc/0x380 [ 15.439156] do_initcall_level+0x103/0x1dd [ 15.439156] do_initcalls+0x4e/0x8e [ 15.439156] do_basic_setup+0x6d/0x74 [ 15.439156] kernel_init_freeable+0x19a/0x21b [ 15.439156] ? rest_init+0xe0/0xe0 [ 15.439156] kernel_init+0x1d/0x240 [ 15.439156] ? rest_init+0xe0/0xe0 [ 15.439156] ret_from_fork+0x1f/0x30 [ 15.439156] </TASK> [ 15.439156] [ 15.439156] The buggy address belongs to the variable: [ 15.439156] init_nf_hooks_bridgep+0x8/0x20 [ 15.439156] [ 15.439156] Memory state around the buggy address: [ 15.439156] ffffffff84e40380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 15.439156] ffffffff84e40400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 15.439156] >ffffffff84e40480: 00 f9 f9 f9 00 00 00 00 00 00 00 00 f9 f9 f9 f9 [ 15.439156] ^ [ 15.439156] ffffffff84e40500: 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 00 00 00 00 [ 15.439156] ffffffff84e40580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 15.439156] ================================================================== Tto fix the issue, it's just simple: - type 'init_nf_hooks_bridge' makes changed to pointer array of type struct nf_hook_entries. - type 'init_nf_hooks_bridgep' makes changed to pointer of pointer and it makes address to the array top of 'init_nf_hooks_bridge'. - get_nf_hooks_bridge() for global init_net should return 'init_nf_hooks_bridgep' which address to pointer array so that netfilter_net_init can initialize. Bug: 316040984 Fixes: b37eb452 ("KMI workaround for CONFIG_NETFILTER_FAMILY_BRIDGE") Change-Id: I29a36da490e1ca18c04fd8c4dea235782f14b83b Signed-off-by:Norihiko Hama <Norihiko.Hama@alpsalpine.com>