linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
@ 2024-01-24 10:14 kovalev
  2024-01-24 10:14 ` [PATCH 1/1] " kovalev
  0 siblings, 1 reply; 12+ messages in thread
From: kovalev @ 2024-01-24 10:14 UTC (permalink / raw)
  To: pablo, laforge, davem, edumazet, kuba, pabeni, osmocom-net-gprs,
	netdev, linux-kernel
  Cc: kovalev, nickel, oficerovas, dutyrok

Syzkaller hit 'general protection fault in gtp_genl_dump_pdp' bug.

This bug is not a vulnerability and is reproduced only when running with root privileges.

dmesg (5.10.200):

gtp: GTP module loaded (pdp ctx size 104 bytes)
gtp: GTP module unloaded
general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
CPU: 0 PID: 2782 Comm: syz-executor139 Not tainted 5.10.200-std-def-alt1 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-alt1 04/01/2014
RIP: 0010:gtp_genl_dump_pdp+0x1b1/0x790 [gtp]
Code: c4 89 c6 e8 b1 07 15 e0 58 45 85 e4 0f 85 97 03 00 00 e8 72 0b 15 e0 48 8b 54 24 20 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80> 3c 02 00 0f 85 ac 05 00 00 48 8b 44 24 20 48 8b 08 48 89 0c 24
RSP: 0018:ffff8881146c73f8 EFLAGS: 00010213
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffffa137fa66
RDX: 0000000000000001 RSI: ffffffffa137f6be RDI: 0000000000000001
gtp: GTP module loaded (pdp ctx size 104 bytes)
RBP: 0000000000000000 R08: 0000000000000000 R09: ffffffff86c4dca7
R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000001
R13: 0000000000000000 R14: ffff888133b04588 R15: 0000000000000000
FS:  00007f2ea15c5740(0000) GS:ffff888140200000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f2ea17686cf CR3: 000000010e56c000 CR4: 0000000000750ef0
PKRU: 55555554
Call Trace:
 genl_lock_dumpit+0x6b/0xa0 net/netlink/genetlink.c:623
 netlink_dump+0x575/0xc70 net/netlink/af_netlink.c:2271
 __netlink_dump_start+0x64e/0x910 net/netlink/af_netlink.c:2376
 genl_family_rcv_msg_dumpit+0x2b8/0x310 net/netlink/genetlink.c:686
 genl_family_rcv_msg net/netlink/genetlink.c:780 [inline]
 genl_rcv_msg+0x450/0x5a0 net/netlink/genetlink.c:800
 netlink_rcv_skb+0x150/0x440 net/netlink/af_netlink.c:2497
 genl_rcv+0x29/0x40 net/netlink/genetlink.c:811
 netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline]
 netlink_unicast+0x54e/0x800 net/netlink/af_netlink.c:1348
 netlink_sendmsg+0x914/0xe00 net/netlink/af_netlink.c:1916
 sock_sendmsg_nosec net/socket.c:651 [inline]
 __sock_sendmsg+0x159/0x190 net/socket.c:663
 ____sys_sendmsg+0x712/0x870 net/socket.c:2376
 ___sys_sendmsg+0xf8/0x170 net/socket.c:2430
 __sys_sendmsg+0xea/0x1b0 net/socket.c:2459
 do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
 entry_SYSCALL_64_after_hwframe+0x62/0xc7
RIP: 0033:0x7f2ea16c2d49
Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d ef 70 0d 00 f7 d8 64 89 01 48
RSP: 002b:00007ffc93f6ed78 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00000000000f4240 RCX: 00007f2ea16c2d49
RDX: 0000000020040840 RSI: 0000000020000940 RDI: 0000000000000003
RBP: 0000000000000000 R08: 00007ffc93f6eb08 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 000000000000be43
R13: 00007ffc93f6ed8c R14: 00007ffc93f6eda0 R15: 00007ffc93f6ed90
Modules linked in: gtp udp_tunnel ide_cd_mod ide_gd_mod cdrom ata_generic pata_acpi ata_piix libata scsi_mod ide_pci_generic ppdev kvm_amd joydev ccp kvm irqbypass crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel bochs_drm drm_vram_helper drm_ttm_helper ttm drm_kms_helper aesni_intel crypto_simd evdev cec input_leds psmouse af_packet i2c_piix4 rc_core cryptd glue_helper serio_raw piix pcspkr intel_agp intel_gtt ide_core tiny_power_button floppy parport_pc parport qemu_fw_cfg button sch_fq_codel fuse drm dm_mod binfmt_misc efi_pstore virtio_rng rng_core ip_tables x_tables autofs4 [last unloaded: gtp]
---[ end trace 3a80aa87ef53345b ]---
RIP: 0010:gtp_genl_dump_pdp+0x1b1/0x790 [gtp]
Code: c4 89 c6 e8 b1 07 15 e0 58 45 85 e4 0f 85 97 03 00 00 e8 72 0b 15 e0 48 8b 54 24 20 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80> 3c 02 00 0f 85 ac 05 00 00 48 8b 44 24 20 48 8b 08 48 89 0c 24
RSP: 0018:ffff8881146c73f8 EFLAGS: 00010213
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffffa137fa66
RDX: 0000000000000001 RSI: ffffffffa137f6be RDI: 0000000000000001
RBP: 0000000000000000 R08: 0000000000000000 R09: ffffffff86c4dca7
R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000001
R13: 0000000000000000 R14: ffff888133b04588 R15: 0000000000000000
FS:  00007f2ea15c5740(0000) GS:ffff888140200000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f2ea17686cf CR3: 000000010e56c000 CR4: 0000000000750ef0
PKRU: 55555554
note: syz-executor139[2782] exited with preempt_count 1
----------------
Code disassembly (best guess), 1 bytes skipped:
   0:	89 c6                	mov    %eax,%esi
   2:	e8 b1 07 15 e0       	callq  0xe01507b8
   7:	58                   	pop    %rax
   8:	45 85 e4             	test   %r12d,%r12d
   b:	0f 85 97 03 00 00    	jne    0x3a8
  11:	e8 72 0b 15 e0       	callq  0xe0150b88
  16:	48 8b 54 24 20       	mov    0x20(%rsp),%rdx
  1b:	48 b8 00 00 00 00 00 fc ff df 	movabs $0xdffffc0000000000,%rax
  25:	48 c1 ea 03          	shr    $0x3,%rdx
* 29:	80 3c 02 00          	cmpb   $0x0,(%rdx,%rax,1) <-- trapping instruction
  2d:	0f 85 ac 05 00 00    	jne    0x5df
  33:	48 8b 44 24 20       	mov    0x20(%rsp),%rax
  38:	48 8b 08             	mov    (%rax),%rcx
  3b:	48 89 0c 24          	mov    %rcx,(%rsp)

C reproducer:
// autogenerated by syzkaller (https://github.com/google/syzkaller)

#define _GNU_SOURCE 

#include <arpa/inet.h>
#include <dirent.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#include <linux/genetlink.h>
#include <linux/if_addr.h>
#include <linux/if_link.h>
#include <linux/in6.h>
#include <linux/neighbour.h>
#include <linux/net.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/veth.h>

static unsigned long long procid;

static void sleep_ms(uint64_t ms)
{
	usleep(ms * 1000);
}

static uint64_t current_time_ms(void)
{
	struct timespec ts;
	if (clock_gettime(CLOCK_MONOTONIC, &ts))
	exit(1);
	return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
}

static bool write_file(const char* file, const char* what, ...)
{
	char buf[1024];
	va_list args;
	va_start(args, what);
	vsnprintf(buf, sizeof(buf), what, args);
	va_end(args);
	buf[sizeof(buf) - 1] = 0;
	int len = strlen(buf);
	int fd = open(file, O_WRONLY | O_CLOEXEC);
	if (fd == -1)
		return false;
	if (write(fd, buf, len) != len) {
		int err = errno;
		close(fd);
		errno = err;
		return false;
	}
	close(fd);
	return true;
}

struct nlmsg {
	char* pos;
	int nesting;
	struct nlattr* nested[8];
	char buf[4096];
};

static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
			 const void* data, int size)
{
	memset(nlmsg, 0, sizeof(*nlmsg));
	struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
	hdr->nlmsg_type = typ;
	hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
	memcpy(hdr + 1, data, size);
	nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
}

static void netlink_attr(struct nlmsg* nlmsg, int typ,
			 const void* data, int size)
{
	struct nlattr* attr = (struct nlattr*)nlmsg->pos;
	attr->nla_len = sizeof(*attr) + size;
	attr->nla_type = typ;
	if (size > 0)
		memcpy(attr + 1, data, size);
	nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
}

static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
			    uint16_t reply_type, int* reply_len, bool dofail)
{
	if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
	exit(1);
	struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
	hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
	struct sockaddr_nl addr;
	memset(&addr, 0, sizeof(addr));
	addr.nl_family = AF_NETLINK;
	ssize_t n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
	if (n != (ssize_t)hdr->nlmsg_len) {
		if (dofail)
	exit(1);
		return -1;
	}
	n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
	if (reply_len)
		*reply_len = 0;
	if (n < 0) {
		if (dofail)
	exit(1);
		return -1;
	}
	if (n < (ssize_t)sizeof(struct nlmsghdr)) {
		errno = EINVAL;
		if (dofail)
	exit(1);
		return -1;
	}
	if (hdr->nlmsg_type == NLMSG_DONE)
		return 0;
	if (reply_len && hdr->nlmsg_type == reply_type) {
		*reply_len = n;
		return 0;
	}
	if (n < (ssize_t)(sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))) {
		errno = EINVAL;
		if (dofail)
	exit(1);
		return -1;
	}
	if (hdr->nlmsg_type != NLMSG_ERROR) {
		errno = EINVAL;
		if (dofail)
	exit(1);
		return -1;
	}
	errno = -((struct nlmsgerr*)(hdr + 1))->error;
	return -errno;
}

static int netlink_query_family_id(struct nlmsg* nlmsg, int sock, const char* family_name, bool dofail)
{
	struct genlmsghdr genlhdr;
	memset(&genlhdr, 0, sizeof(genlhdr));
	genlhdr.cmd = CTRL_CMD_GETFAMILY;
	netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
	netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, family_name, strnlen(family_name, GENL_NAMSIZ - 1) + 1);
	int n = 0;
	int err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n, dofail);
	if (err < 0) {
		return -1;
	}
	uint16_t id = 0;
	struct nlattr* attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(genlhdr)));
	for (; (char*)attr < nlmsg->buf + n; attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
		if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
			id = *(uint16_t*)(attr + 1);
			break;
		}
	}
	if (!id) {
		errno = EINVAL;
		return -1;
	}
	recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
	return id;
}

static long syz_genetlink_get_family_id(volatile long name, volatile long sock_arg)
{
	int fd = sock_arg;
	if (fd < 0) {
		fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
		if (fd == -1) {
			return -1;
		}
	}
	struct nlmsg nlmsg_tmp;
	int ret = netlink_query_family_id(&nlmsg_tmp, fd, (char*)name, false);
	if ((int)sock_arg < 0)
		close(fd);
	if (ret < 0) {
		return -1;
	}
	return ret;
}

static void kill_and_wait(int pid, int* status)
{
	kill(-pid, SIGKILL);
	kill(pid, SIGKILL);
	for (int i = 0; i < 100; i++) {
		if (waitpid(-1, status, WNOHANG | __WALL) == pid)
			return;
		usleep(1000);
	}
	DIR* dir = opendir("/sys/fs/fuse/connections");
	if (dir) {
		for (;;) {
			struct dirent* ent = readdir(dir);
			if (!ent)
				break;
			if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
				continue;
			char abort[300];
			snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort", ent->d_name);
			int fd = open(abort, O_WRONLY);
			if (fd == -1) {
				continue;
			}
			if (write(fd, abort, 1) < 0) {
			}
			close(fd);
		}
		closedir(dir);
	} else {
	}
	while (waitpid(-1, status, __WALL) != pid) {
	}
}

static void setup_test()
{
	prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
	setpgrp();
	write_file("/proc/self/oom_score_adj", "1000");
}

static void execute_one(void);

#define WAIT_FLAGS __WALL

static void loop(void)
{
	int iter = 0;
	for (;; iter++) {
		int pid = fork();
		if (pid < 0)
	exit(1);
		if (pid == 0) {
			setup_test();
			execute_one();
			exit(0);
		}
		int status = 0;
		uint64_t start = current_time_ms();
		for (;;) {
			if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
				break;
			sleep_ms(1);
			if (current_time_ms() - start < 5000)
				continue;
			kill_and_wait(pid, &status);
			break;
		}
	}
}

uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};

void execute_one(void)
{
		intptr_t res = 0;
memcpy((void*)0x20000140, "gtp\000", 4);
	syscall(__NR_delete_module, 0x20000140ul, 0x5000000ul);
	res = syscall(__NR_socket, 0x10ul, 3ul, 0x10);
	if (res != -1)
		r[0] = res;
memcpy((void*)0x20000100, "gtp\000", 4);
	res = -1;
res = syz_genetlink_get_family_id(0x20000100, -1);
	if (res != -1)
		r[1] = res;
*(uint64_t*)0x20000940 = 0;
*(uint32_t*)0x20000948 = 0;
*(uint64_t*)0x20000950 = 0x20000900;
*(uint64_t*)0x20000900 = 0x20000140;
memcpy((void*)0x20000140, "$\000\000\000", 4);
*(uint16_t*)0x20000144 = r[1];
memcpy((void*)0x20000146, "\x13\x03\xfc\xff\xff\xff\xfe\xdb\xdf\x25\x02\x00\x00\x00\x08\x00\x02\x00\x01\x00\x00\x00\x08\x00\x01\x00", 26);
*(uint32_t*)0x20000160 = 0;
*(uint64_t*)0x20000164 = r[1];
*(uint32_t*)0x2000016c = -1;
*(uint64_t*)0x20000170 = -1;
sprintf((char*)0x20000178, "0x%016llx", (long long)-1);
*(uint64_t*)0x20000908 = 0x24;
*(uint64_t*)0x20000958 = 1;
*(uint64_t*)0x20000960 = 0;
*(uint64_t*)0x20000968 = 0;
*(uint32_t*)0x20000970 = 0;
	syscall(__NR_sendmsg, r[0], 0x20000940ul, 0x20040840ul);

}
int main(void)
{
		syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
	syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
	syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
	for (procid = 0; procid < 6; procid++) {
		if (fork() == 0) {
			loop();
		}
	}
	sleep(1000000);
	return 0;
}

The bug is also reproduced on the latest stable kernels with the KASAN
sanitizer disabled:

dmesg (6.6.13):

[  523.894617] gtp: GTP module loaded (pdp ctx size 104 bytes)
[  523.908033] gtp: GTP module unloaded
[  523.914798] BUG: kernel NULL pointer dereference, address: 0000000000000012
[  523.915255] #PF: supervisor read access in kernel mode
[  523.915255] #PF: error_code(0x0000) - not-present page
[  523.915255] PGD 2a0b9067 P4D 2a0b9067 PUD 6ccc067 PMD 0 
[  523.915255] Oops: 0000 [#1] PREEMPT SMP NOPTI
[  523.915255] CPU: 1 PID: 9263 Comm: repro7 Not tainted 6.6.13-un-def-alt1 #1
[  523.915255] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.0-alt1 04/01/2014
[  523.915255] RIP: 0010:gtp_genl_dump_pdp+0x82/0x190 [gtp]
[  523.915255] Code: 70 00 74 21 48 83 c4 18 5b 5d 41 5c 41 5d 41 5e 41 5f 31 d2 31 c9 31 f6 31 ff 45 31 c0 45 31 c9 c3 cc cc cc cc e8 0e 0b 57 c0 <4c> 8b 23 49 39 dc 74 22 44 89 6c 24 04 44 8b 6c 24 08 4d 85 ff 74
[  523.915255] RSP: 0018:ffffc900017338a8 EFLAGS: 00010246
[  523.915255] RAX: 0000000000000000 RBX: 0000000000000012 RCX: 0000000000000000
[  523.915255] RDX: 0000000000000000 RSI: ffff88800713bb60 RDI: 0000000000000000
[  523.915255] RBP: ffff88800632b200 R08: 0000000000000000 R09: 0000000000000000
[  523.915255] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
[  523.915255] R13: 0000000000000000 R14: ffff88800713bb60 R15: 0000000000000000
[  523.915255] FS:  00007f2bcb83f740(0000) GS:ffff88807dc80000(0000) knlGS:0000000000000000
[  523.915255] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  523.915255] CR2: 0000000000000012 CR3: 0000000052420000 CR4: 0000000000750ee0
[  523.915255] PKRU: 55555554
[  523.915255] Call Trace:
[  523.915255]  <TASK>
[  523.915255]  ? __die+0x1f/0x70
[  523.915255]  ? page_fault_oops+0x14d/0x4a0
[  523.915255]  ? exc_page_fault+0x7b/0x180
[  523.915255]  ? asm_exc_page_fault+0x22/0x30
[  523.915255]  ? gtp_genl_dump_pdp+0x82/0x190 [gtp]
[  523.915255]  ? gtp_genl_dump_pdp+0x82/0x190 [gtp]
[  523.915255]  genl_dumpit+0x2f/0x90
[  523.915255]  netlink_dump+0x126/0x320
[  523.915255]  __netlink_dump_start+0x1da/0x2a0
[  523.915255]  genl_family_rcv_msg_dumpit+0x93/0x100
[  523.915255]  ? __pfx_genl_start+0x10/0x10
[  523.915255]  ? __pfx_genl_dumpit+0x10/0x10
[  523.915255]  ? __pfx_genl_done+0x10/0x10
[  523.915255]  genl_rcv_msg+0x112/0x2a0
[  523.915255]  ? __pfx_gtp_genl_dump_pdp+0x10/0x10 [gtp]
[  523.915255]  ? __pfx_genl_rcv_msg+0x10/0x10
[  523.915255]  netlink_rcv_skb+0x54/0x110
[  523.915255]  genl_rcv+0x24/0x40
[  523.915255]  netlink_unicast+0x19f/0x290
[  523.915255]  netlink_sendmsg+0x250/0x4e0
[  523.915255]  ____sys_sendmsg+0x376/0x3b0
[  523.915255]  ? copy_msghdr_from_user+0x6d/0xb0
[  523.915255]  ___sys_sendmsg+0x86/0xe0
[  523.915255]  ? do_fault+0x296/0x470
[  523.915255]  ? __handle_mm_fault+0x771/0xda0
[  523.915255]  __sys_sendmsg+0x57/0xb0
[  523.915255]  do_syscall_64+0x59/0x90
[  523.915255]  ? ct_kernel_exit.isra.0+0x71/0x90
[  523.915255]  ? __ct_user_enter+0x5a/0xd0
[  523.915255]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
[  523.915255] RIP: 0033:0x7f2bcb93cd49
[  523.915255] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d ef 70 0d 00 f7 d8 64 89 01 48
[  523.915255] RSP: 002b:00007ffe5d907708 EFLAGS: 00000202 ORIG_RAX: 000000000000002e
[  523.915255] RAX: ffffffffffffffda RBX: 0000562f4a49f0a0 RCX: 00007f2bcb93cd49
[  523.915255] RDX: 0000000020040840 RSI: 0000000020000940 RDI: 0000000000000003
[  523.915255] RBP: 00007ffe5d907720 R08: 00007ffe5d907498 R09: 00007ffe5d907720
[  523.915255] R10: 0000000000000000 R11: 0000000000000202 R12: 0000562f4a49e210
[  523.915255] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[  523.915255]  </TASK>

[PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()


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

* [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-01-24 10:14 [PATCH 0/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp() kovalev
@ 2024-01-24 10:14 ` kovalev
  2024-01-24 10:42   ` Eric Dumazet
  2024-01-24 10:57   ` Eric Dumazet
  0 siblings, 2 replies; 12+ messages in thread
From: kovalev @ 2024-01-24 10:14 UTC (permalink / raw)
  To: pablo, laforge, davem, edumazet, kuba, pabeni, osmocom-net-gprs,
	netdev, linux-kernel
  Cc: kovalev, nickel, oficerovas, dutyrok

From: Vasiliy Kovalev <kovalev@altlinux.org>

After unloading the module, an instance continues to exist that accesses
outdated memory addresses.

To prevent this, the dump_pdp_en flag has been added, which blocks the
dump of pdp contexts by a false value. And only after these checks can
the net_generic() function be called.

These errors were found using the syzkaller program:

Syzkaller hit 'general protection fault in gtp_genl_dump_pdp' bug.
gtp: GTP module loaded (pdp ctx size 104 bytes)
gtp: GTP module unloaded
general protection fault, probably for non-canonical address
0xdffffc0000000001:0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
CPU: 0 PID: 2782 Comm: syz-executor139 Not tainted 5.10.200-std-def-alt1 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-alt1
RIP: 0010:gtp_genl_dump_pdp+0x1b1/0x790 [gtp]
...
Call Trace:
 genl_lock_dumpit+0x6b/0xa0 net/netlink/genetlink.c:623
 netlink_dump+0x575/0xc70 net/netlink/af_netlink.c:2271
 __netlink_dump_start+0x64e/0x910 net/netlink/af_netlink.c:2376
 genl_family_rcv_msg_dumpit+0x2b8/0x310 net/netlink/genetlink.c:686
 genl_family_rcv_msg net/netlink/genetlink.c:780 [inline]
 genl_rcv_msg+0x450/0x5a0 net/netlink/genetlink.c:800
 netlink_rcv_skb+0x150/0x440 net/netlink/af_netlink.c:2497
 genl_rcv+0x29/0x40 net/netlink/genetlink.c:811
 netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline]
 netlink_unicast+0x54e/0x800 net/netlink/af_netlink.c:1348
 netlink_sendmsg+0x914/0xe00 net/netlink/af_netlink.c:1916
 sock_sendmsg_nosec net/socket.c:651 [inline]
 __sock_sendmsg+0x159/0x190 net/socket.c:663
 ____sys_sendmsg+0x712/0x870 net/socket.c:2376
 ___sys_sendmsg+0xf8/0x170 net/socket.c:2430
 __sys_sendmsg+0xea/0x1b0 net/socket.c:2459
 do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
 entry_SYSCALL_64_after_hwframe+0x62/0xc7
RIP: 0033:0x7f2ea16c2d49

Fixes: 94a6d9fb88df ("gtp: fix wrong condition in gtp_genl_dump_pdp()")
Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
---
 drivers/net/gtp.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 477b4d4f860bd3..3fc4639711cd83 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -1675,6 +1675,8 @@ static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info)
 	return err;
 }
 
+static bool dump_pdp_en;
+
 static int gtp_genl_dump_pdp(struct sk_buff *skb,
 				struct netlink_callback *cb)
 {
@@ -1684,12 +1686,19 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb,
 	struct pdp_ctx *pctx;
 	struct gtp_net *gn;
 
-	gn = net_generic(net, gtp_net_id);
-
-	if (cb->args[4])
+	/* Do not allow further operations if the module is
+	 * unloaded before or after the process is blocked.
+	 */
+	if (!dump_pdp_en)
 		return 0;
 
 	rcu_read_lock();
+	if (!dump_pdp_en || cb->args[4]) {
+		rcu_read_unlock();
+		return 0;
+	}
+	gn = net_generic(net, gtp_net_id);
+
 	list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) {
 		if (last_gtp && last_gtp != gtp)
 			continue;
@@ -1914,6 +1923,8 @@ static int __init gtp_init(void)
 	if (err < 0)
 		goto unreg_genl_family;
 
+	dump_pdp_en = true;
+
 	pr_info("GTP module loaded (pdp ctx size %zd bytes)\n",
 		sizeof(struct pdp_ctx));
 	return 0;
@@ -1930,6 +1941,7 @@ late_initcall(gtp_init);
 
 static void __exit gtp_fini(void)
 {
+	dump_pdp_en = false;
 	genl_unregister_family(&gtp_genl_family);
 	rtnl_link_unregister(&gtp_link_ops);
 	unregister_pernet_subsys(&gtp_net_ops);
-- 
2.33.8


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

* Re: [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-01-24 10:14 ` [PATCH 1/1] " kovalev
@ 2024-01-24 10:42   ` Eric Dumazet
  2024-01-24 10:57   ` Eric Dumazet
  1 sibling, 0 replies; 12+ messages in thread
From: Eric Dumazet @ 2024-01-24 10:42 UTC (permalink / raw)
  To: kovalev
  Cc: pablo, laforge, davem, kuba, pabeni, osmocom-net-gprs, netdev,
	linux-kernel, nickel, oficerovas, dutyrok

On Wed, Jan 24, 2024 at 11:14 AM <kovalev@altlinux.org> wrote:
>
> From: Vasiliy Kovalev <kovalev@altlinux.org>
>
> After unloading the module, an instance continues to exist that accesses
> outdated memory addresses.
>
> To prevent this, the dump_pdp_en flag has been added, which blocks the
> dump of pdp contexts by a false value. And only after these checks can
> the net_generic() function be called.
>
> These errors were found using the syzkaller program:
>
> Syzkaller hit 'general protection fault in gtp_genl_dump_pdp' bug.
> gtp: GTP module loaded (pdp ctx size 104 bytes)
> gtp: GTP module unloaded
> general protection fault, probably for non-canonical address
> 0xdffffc0000000001:0000 [#1] SMP KASAN NOPTI
> KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
> CPU: 0 PID: 2782 Comm: syz-executor139 Not tainted 5.10.200-std-def-alt1 #1
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-alt1
> RIP: 0010:gtp_genl_dump_pdp+0x1b1/0x790 [gtp]
> ...
> Call Trace:
>  genl_lock_dumpit+0x6b/0xa0 net/netlink/genetlink.c:623
>  netlink_dump+0x575/0xc70 net/netlink/af_netlink.c:2271
>  __netlink_dump_start+0x64e/0x910 net/netlink/af_netlink.c:2376
>  genl_family_rcv_msg_dumpit+0x2b8/0x310 net/netlink/genetlink.c:686
>  genl_family_rcv_msg net/netlink/genetlink.c:780 [inline]
>  genl_rcv_msg+0x450/0x5a0 net/netlink/genetlink.c:800
>  netlink_rcv_skb+0x150/0x440 net/netlink/af_netlink.c:2497
>  genl_rcv+0x29/0x40 net/netlink/genetlink.c:811
>  netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline]
>  netlink_unicast+0x54e/0x800 net/netlink/af_netlink.c:1348
>  netlink_sendmsg+0x914/0xe00 net/netlink/af_netlink.c:1916
>  sock_sendmsg_nosec net/socket.c:651 [inline]
>  __sock_sendmsg+0x159/0x190 net/socket.c:663
>  ____sys_sendmsg+0x712/0x870 net/socket.c:2376
>  ___sys_sendmsg+0xf8/0x170 net/socket.c:2430
>  __sys_sendmsg+0xea/0x1b0 net/socket.c:2459
>  do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
>  entry_SYSCALL_64_after_hwframe+0x62/0xc7
> RIP: 0033:0x7f2ea16c2d49
>
> Fixes: 94a6d9fb88df ("gtp: fix wrong condition in gtp_genl_dump_pdp()")
> Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
> ---
>  drivers/net/gtp.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
> index 477b4d4f860bd3..3fc4639711cd83 100644
> --- a/drivers/net/gtp.c
> +++ b/drivers/net/gtp.c
> @@ -1675,6 +1675,8 @@ static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info)
>         return err;
>  }
>
> +static bool dump_pdp_en;
> +

Hmm, it seems there is a missing try_module_get() somewhere...

__netlink_dump_start() does one, so perhaps we reach __netlink_dump_start()
with a NULL in control->module ?

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

* Re: [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-01-24 10:14 ` [PATCH 1/1] " kovalev
  2024-01-24 10:42   ` Eric Dumazet
@ 2024-01-24 10:57   ` Eric Dumazet
  2024-01-24 11:20     ` kovalev
  1 sibling, 1 reply; 12+ messages in thread
From: Eric Dumazet @ 2024-01-24 10:57 UTC (permalink / raw)
  To: kovalev
  Cc: pablo, laforge, davem, kuba, pabeni, osmocom-net-gprs, netdev,
	linux-kernel, nickel, oficerovas, dutyrok

On Wed, Jan 24, 2024 at 11:14 AM <kovalev@altlinux.org> wrote:
>
> From: Vasiliy Kovalev <kovalev@altlinux.org>
>
> After unloading the module, an instance continues to exist that accesses
> outdated memory addresses.
>
> To prevent this, the dump_pdp_en flag has been added, which blocks the
> dump of pdp contexts by a false value. And only after these checks can
> the net_generic() function be called.
>
> These errors were found using the syzkaller program:
>
> Syzkaller hit 'general protection fault in gtp_genl_dump_pdp' bug.
> gtp: GTP module loaded (pdp ctx size 104 bytes)
> gtp: GTP module unloaded
> general protection fault, probably for non-canonical address
> 0xdffffc0000000001:0000 [#1] SMP KASAN NOPTI
> KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
> CPU: 0 PID: 2782 Comm: syz-executor139 Not tainted 5.10.200-std-def-alt1 #1

Oh wait, this is a 5.10 kernel ?

Please generate a stack trace using a recent tree, it is possible the
bug has been fixed already.

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

* Re: [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-01-24 10:57   ` Eric Dumazet
@ 2024-01-24 11:20     ` kovalev
  2024-01-24 11:52       ` Eric Dumazet
  2024-01-29 12:02       ` Pablo Neira Ayuso
  0 siblings, 2 replies; 12+ messages in thread
From: kovalev @ 2024-01-24 11:20 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: pablo, laforge, davem, kuba, pabeni, osmocom-net-gprs, netdev,
	linux-kernel, nickel, oficerovas, dutyrok, kovalev

24.01.2024 13:57, Eric Dumazet wrote:
> Oh wait, this is a 5.10 kernel ?
Yes, but the bug is reproduced on the latest stable kernels.
> Please generate a stack trace using a recent tree, it is possible the
> bug has been fixed already.

See [PATCH 0/1] above, there's a stack for the 6.6.13 kernel at the 
bottom of the message.

[  523.915255] Call Trace:
[  523.915255]  <TASK>
[  523.915255]  ? __die+0x1f/0x70
[  523.915255]  ? page_fault_oops+0x14d/0x4a0
[  523.915255]  ? exc_page_fault+0x7b/0x180
[  523.915255]  ? asm_exc_page_fault+0x22/0x30
[  523.915255]  ? gtp_genl_dump_pdp+0x82/0x190 [gtp]
[  523.915255]  ? gtp_genl_dump_pdp+0x82/0x190 [gtp]
[  523.915255]  genl_dumpit+0x2f/0x90
[  523.915255]  netlink_dump+0x126/0x320
[  523.915255]  __netlink_dump_start+0x1da/0x2a0
[  523.915255]  genl_family_rcv_msg_dumpit+0x93/0x100
[  523.915255]  ? __pfx_genl_start+0x10/0x10
[  523.915255]  ? __pfx_genl_dumpit+0x10/0x10
[  523.915255]  ? __pfx_genl_done+0x10/0x10
[  523.915255]  genl_rcv_msg+0x112/0x2a0
[  523.915255]  ? __pfx_gtp_genl_dump_pdp+0x10/0x10 [gtp]
[  523.915255]  ? __pfx_genl_rcv_msg+0x10/0x10
[  523.915255]  netlink_rcv_skb+0x54/0x110
[  523.915255]  genl_rcv+0x24/0x40
[  523.915255]  netlink_unicast+0x19f/0x290
[  523.915255]  netlink_sendmsg+0x250/0x4e0
[  523.915255]  ____sys_sendmsg+0x376/0x3b0
[  523.915255]  ? copy_msghdr_from_user+0x6d/0xb0
[  523.915255]  ___sys_sendmsg+0x86/0xe0
[  523.915255]  ? do_fault+0x296/0x470
[  523.915255]  ? __handle_mm_fault+0x771/0xda0
[  523.915255]  __sys_sendmsg+0x57/0xb0
[  523.915255]  do_syscall_64+0x59/0x90
[  523.915255]  ? ct_kernel_exit.isra.0+0x71/0x90
[  523.915255]  ? __ct_user_enter+0x5a/0xd0
[  523.915255]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
[  523.915255] RIP: 0033:0x7f2bcb93cd49

-- 
Regards,
Vasiliy Kovalev


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

* Re: [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-01-24 11:20     ` kovalev
@ 2024-01-24 11:52       ` Eric Dumazet
  2024-02-09 18:16         ` kovalev
  2024-01-29 12:02       ` Pablo Neira Ayuso
  1 sibling, 1 reply; 12+ messages in thread
From: Eric Dumazet @ 2024-01-24 11:52 UTC (permalink / raw)
  To: kovalev
  Cc: pablo, laforge, davem, kuba, pabeni, osmocom-net-gprs, netdev,
	linux-kernel, nickel, oficerovas, dutyrok

On Wed, Jan 24, 2024 at 12:20 PM <kovalev@altlinux.org> wrote:
>
> 24.01.2024 13:57, Eric Dumazet wrote:
> > Oh wait, this is a 5.10 kernel ?
> Yes, but the bug is reproduced on the latest stable kernels.
> > Please generate a stack trace using a recent tree, it is possible the
> > bug has been fixed already.
>
> See [PATCH 0/1] above, there's a stack for the 6.6.13 kernel at the
> bottom of the message.

Ah, ok. Not sure why you sent a cover letter for a single patch...

Setting a boolean, in a module that can disappear will not prevent the
module from disappearing.

This work around might work, or might not work, depending on timing,
preemptions, ....

Thanks.

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

* Re: [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-01-24 11:20     ` kovalev
  2024-01-24 11:52       ` Eric Dumazet
@ 2024-01-29 12:02       ` Pablo Neira Ayuso
  2024-01-29 16:53         ` kovalev
  1 sibling, 1 reply; 12+ messages in thread
From: Pablo Neira Ayuso @ 2024-01-29 12:02 UTC (permalink / raw)
  To: kovalev
  Cc: Eric Dumazet, laforge, davem, kuba, pabeni, osmocom-net-gprs,
	netdev, linux-kernel, nickel, oficerovas, dutyrok

Hi,

On Wed, Jan 24, 2024 at 02:20:04PM +0300, kovalev@altlinux.org wrote:
> 24.01.2024 13:57, Eric Dumazet wrote:
> > Oh wait, this is a 5.10 kernel ?
>
> Yes, but the bug is reproduced on the latest stable kernels.
>
> > Please generate a stack trace using a recent tree, it is possible the
> > bug has been fixed already.

__netlink_dump_start() is called at the beginning of the dump, which is
grabbing a reference on this module.

do you have a reproducer?

> See [PATCH 0/1] above, there's a stack for the 6.6.13 kernel at the bottom
> of the message.
> 
> [  523.915255] Call Trace:
> [  523.915255]  <TASK>
> [  523.915255]  ? __die+0x1f/0x70
> [  523.915255]  ? page_fault_oops+0x14d/0x4a0
> [  523.915255]  ? exc_page_fault+0x7b/0x180
> [  523.915255]  ? asm_exc_page_fault+0x22/0x30
> [  523.915255]  ? gtp_genl_dump_pdp+0x82/0x190 [gtp]
> [  523.915255]  ? gtp_genl_dump_pdp+0x82/0x190 [gtp]
> [  523.915255]  genl_dumpit+0x2f/0x90
> [  523.915255]  netlink_dump+0x126/0x320
> [  523.915255]  __netlink_dump_start+0x1da/0x2a0
> [  523.915255]  genl_family_rcv_msg_dumpit+0x93/0x100
> [  523.915255]  ? __pfx_genl_start+0x10/0x10
> [  523.915255]  ? __pfx_genl_dumpit+0x10/0x10
> [  523.915255]  ? __pfx_genl_done+0x10/0x10
> [  523.915255]  genl_rcv_msg+0x112/0x2a0
> [  523.915255]  ? __pfx_gtp_genl_dump_pdp+0x10/0x10 [gtp]
> [  523.915255]  ? __pfx_genl_rcv_msg+0x10/0x10
> [  523.915255]  netlink_rcv_skb+0x54/0x110
> [  523.915255]  genl_rcv+0x24/0x40
> [  523.915255]  netlink_unicast+0x19f/0x290
> [  523.915255]  netlink_sendmsg+0x250/0x4e0
> [  523.915255]  ____sys_sendmsg+0x376/0x3b0
> [  523.915255]  ? copy_msghdr_from_user+0x6d/0xb0
> [  523.915255]  ___sys_sendmsg+0x86/0xe0
> [  523.915255]  ? do_fault+0x296/0x470
> [  523.915255]  ? __handle_mm_fault+0x771/0xda0
> [  523.915255]  __sys_sendmsg+0x57/0xb0
> [  523.915255]  do_syscall_64+0x59/0x90
> [  523.915255]  ? ct_kernel_exit.isra.0+0x71/0x90
> [  523.915255]  ? __ct_user_enter+0x5a/0xd0
> [  523.915255]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
> [  523.915255] RIP: 0033:0x7f2bcb93cd49
> 
> -- 
> Regards,
> Vasiliy Kovalev
> 

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

* Re: [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-01-29 12:02       ` Pablo Neira Ayuso
@ 2024-01-29 16:53         ` kovalev
  0 siblings, 0 replies; 12+ messages in thread
From: kovalev @ 2024-01-29 16:53 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: Eric Dumazet, laforge, davem, kuba, pabeni, osmocom-net-gprs,
	netdev, linux-kernel, nickel, oficerovas, dutyrok

29.01.2024 15:02, Pablo Neira Ayuso wrote:
> __netlink_dump_start() is called at the beginning of the dump, which is
> grabbing a reference on this module.
>
> do you have a reproducer?
Hi, yes, in the cover letter [PATCH 0/1] 
https://lore.kernel.org/all/20240124101404.161655-1-kovalev@altlinux.org/

-- 
Regards,
Vasiliy Kovalev


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

* Re: [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-01-24 11:52       ` Eric Dumazet
@ 2024-02-09 18:16         ` kovalev
  2024-02-09 19:21           ` Eric Dumazet
  0 siblings, 1 reply; 12+ messages in thread
From: kovalev @ 2024-02-09 18:16 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: pablo, laforge, davem, kuba, pabeni, osmocom-net-gprs, netdev,
	linux-kernel, nickel, oficerovas, dutyrok

Hi,

24.01.2024 14:52, Eric Dumazet wrote:
> On Wed, Jan 24, 2024 at 12:20 PM <kovalev@altlinux.org> wrote:
>> 24.01.2024 13:57, Eric Dumazet wrote:
>>> Oh wait, this is a 5.10 kernel ?
>> Yes, but the bug is reproduced on the latest stable kernels.
>>> Please generate a stack trace using a recent tree, it is possible the
>>> bug has been fixed already.
>> See [PATCH 0/1] above, there's a stack for the 6.6.13 kernel at the
>> bottom of the message.
> Ah, ok. Not sure why you sent a cover letter for a single patch...
>
> Setting a boolean, in a module that can disappear will not prevent the
> module from disappearing.
>
> This work around might work, or might not work, depending on timing,
> preemptions, ....
>
> Thanks.

I tested running the reproducer [1] on the 6.8-rc3 kernel, the crash 
occurs in less than 10 seconds and the qemu VM restarts:

dmesg -w:

[  106.941736] gtp: GTP module unloaded
[  106.962548] gtp: GTP module loaded (pdp ctx size 104 bytes)
[  107.014691] gtp: GTP module unloaded
[  107.041554] gtp: GTP module loaded (pdp ctx size 104 bytes)
[  107.082283] gtp: GTP module unloaded
[  107.123268] general protection fault, probably for non-canonical 
address 0xdffffc0000000002: 0000 [#1] PREEMPT SMP KASAN NOPTI
[  107.124050] KASAN: null-ptr-deref in range 
[0x0000000000000010-0x0000000000000017]
[  107.124339] CPU: 1 PID: 5826 Comm: gtp Not tainted 
6.8.0-rc3-std-def-alt1 #1
[  107.124604] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 
1.16.0-alt1 04/01/2014
[  107.124916] RIP: 0010:gtp_genl_dump_pdp+0x1be/0x800 [gtp]
[  107.125141] Code: c6 89 c6 e8 64 e9 86 df 58 45 85 f6 0f 85 4e 04 00 
00 e8 c5 ee 86 df 48 8b 54 24 18 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 
03 <80> 3c 02 00 0f 85 de 05 00 00 48 8b 44 24 18 4c 8b 30 4c 39 f0 74
[  107.125960] RSP: 0018:ffff888014107220 EFLAGS: 00010202
[  107.126164] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 
0000000000000000
[  107.126434] RDX: 0000000000000002 RSI: 0000000000000000 RDI: 
0000000000000000
[  107.126707] RBP: 0000000000000000 R08: 0000000000000000 R09: 
0000000000000000
[  107.126976] R10: 0000000000000000 R11: 0000000000000000 R12: 
0000000000000000
[  107.127245] R13: ffff88800fcda588 R14: 0000000000000001 R15: 
0000000000000000
[  107.127515] FS:  00007f1be4eb05c0(0000) GS:ffff88806ce80000(0000) 
knlGS:0000000000000000
[  107.127955] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  107.128177] CR2: 00007f1be4e766cf CR3: 000000000c33e000 CR4: 
0000000000750ef0
[  107.128450] PKRU: 55555554
[  107.128577] Call Trace:
[  107.128699]  <TASK>
[  107.128790]  ? show_regs+0x90/0xa0
[  107.128935]  ? die_addr+0x50/0xd0
[  107.129075]  ? exc_general_protection+0x148/0x220
[  107.129267]  ? asm_exc_general_protection+0x22/0x30
[  107.129469]  ? gtp_genl_dump_pdp+0x1be/0x800 [gtp]
[  107.129677]  ? __alloc_skb+0x1dd/0x350
[  107.129831]  ? __pfx___alloc_skb+0x10/0x10
[  107.129999]  genl_dumpit+0x11d/0x230
[  107.130150]  netlink_dump+0x5b9/0xce0
[  107.130301]  ? lockdep_hardirqs_on_prepare+0x253/0x430
[  107.130503]  ? __pfx_netlink_dump+0x10/0x10
[  107.130686]  ? kasan_save_track+0x10/0x40
[  107.130849]  ? __kasan_kmalloc+0x9b/0xa0
[  107.131009]  ? genl_start+0x675/0x970
[  107.131162]  __netlink_dump_start+0x6fc/0x9f0
[  107.131341]  genl_family_rcv_msg_dumpit+0x1bb/0x2d0
[  107.131538]  ? __pfx_genl_family_rcv_msg_dumpit+0x10/0x10
[  107.131754]  ? genl_op_from_small+0x2a/0x440
[  107.131972]  ? cap_capable+0x1d0/0x240
[  107.132127]  ? __pfx_genl_start+0x10/0x10
[  107.132292]  ? __pfx_genl_dumpit+0x10/0x10
[  107.132461]  ? __pfx_genl_done+0x10/0x10
[  107.132645]  ? security_capable+0x9d/0xe0

With the proposed patch applied, such a crash is not observed during 
long-term testing.

[1] 
https://lore.kernel.org/lkml/20240124101404.161655-1-kovalev@altlinux.org/T/#mf9b411baec52858b1c9118c671f26a6dc424e7b4

-- 
Regards,
Vasiliy Kovalev


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

* Re: [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-02-09 18:16         ` kovalev
@ 2024-02-09 19:21           ` Eric Dumazet
  2024-02-14 16:50             ` kovalev
  0 siblings, 1 reply; 12+ messages in thread
From: Eric Dumazet @ 2024-02-09 19:21 UTC (permalink / raw)
  To: kovalev
  Cc: pablo, laforge, davem, kuba, pabeni, osmocom-net-gprs, netdev,
	linux-kernel, nickel, oficerovas, dutyrok

On Fri, Feb 9, 2024 at 7:16 PM <kovalev@altlinux.org> wrote:
>
> Hi,
>
> 24.01.2024 14:52, Eric Dumazet wrote:
> > On Wed, Jan 24, 2024 at 12:20 PM <kovalev@altlinux.org> wrote:
> >> 24.01.2024 13:57, Eric Dumazet wrote:
> >>> Oh wait, this is a 5.10 kernel ?
> >> Yes, but the bug is reproduced on the latest stable kernels.
> >>> Please generate a stack trace using a recent tree, it is possible the
> >>> bug has been fixed already.
> >> See [PATCH 0/1] above, there's a stack for the 6.6.13 kernel at the
> >> bottom of the message.
> > Ah, ok. Not sure why you sent a cover letter for a single patch...
> >
> > Setting a boolean, in a module that can disappear will not prevent the
> > module from disappearing.
> >
> > This work around might work, or might not work, depending on timing,
> > preemptions, ....
> >
> > Thanks.
>
> I tested running the reproducer [1] on the 6.8-rc3 kernel, the crash
> occurs in less than 10 seconds and the qemu VM restarts:
>
> dmesg -w:
>
> [  106.941736] gtp: GTP module unloaded
> [  106.962548] gtp: GTP module loaded (pdp ctx size 104 bytes)
> [  107.014691] gtp: GTP module unloaded
> [  107.041554] gtp: GTP module loaded (pdp ctx size 104 bytes)
> [  107.082283] gtp: GTP module unloaded
> [  107.123268] general protection fault, probably for non-canonical
> address 0xdffffc0000000002: 0000 [#1] PREEMPT SMP KASAN NOPTI
> [  107.124050] KASAN: null-ptr-deref in range
> [0x0000000000000010-0x0000000000000017]
> [  107.124339] CPU: 1 PID: 5826 Comm: gtp Not tainted
> 6.8.0-rc3-std-def-alt1 #1
> [  107.124604] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
> 1.16.0-alt1 04/01/2014
> [  107.124916] RIP: 0010:gtp_genl_dump_pdp+0x1be/0x800 [gtp]
> [  107.125141] Code: c6 89 c6 e8 64 e9 86 df 58 45 85 f6 0f 85 4e 04 00
> 00 e8 c5 ee 86 df 48 8b 54 24 18 48 b8 00 00 00 00 00 fc ff df 48 c1 ea
> 03 <80> 3c 02 00 0f 85 de 05 00 00 48 8b 44 24 18 4c 8b 30 4c 39 f0 74
> [  107.125960] RSP: 0018:ffff888014107220 EFLAGS: 00010202
> [  107.126164] RAX: dffffc0000000000 RBX: 0000000000000000 RCX:
> 0000000000000000
> [  107.126434] RDX: 0000000000000002 RSI: 0000000000000000 RDI:
> 0000000000000000
> [  107.126707] RBP: 0000000000000000 R08: 0000000000000000 R09:
> 0000000000000000
> [  107.126976] R10: 0000000000000000 R11: 0000000000000000 R12:
> 0000000000000000
> [  107.127245] R13: ffff88800fcda588 R14: 0000000000000001 R15:
> 0000000000000000
> [  107.127515] FS:  00007f1be4eb05c0(0000) GS:ffff88806ce80000(0000)
> knlGS:0000000000000000
> [  107.127955] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [  107.128177] CR2: 00007f1be4e766cf CR3: 000000000c33e000 CR4:
> 0000000000750ef0
> [  107.128450] PKRU: 55555554
> [  107.128577] Call Trace:
> [  107.128699]  <TASK>
> [  107.128790]  ? show_regs+0x90/0xa0
> [  107.128935]  ? die_addr+0x50/0xd0
> [  107.129075]  ? exc_general_protection+0x148/0x220
> [  107.129267]  ? asm_exc_general_protection+0x22/0x30
> [  107.129469]  ? gtp_genl_dump_pdp+0x1be/0x800 [gtp]
> [  107.129677]  ? __alloc_skb+0x1dd/0x350
> [  107.129831]  ? __pfx___alloc_skb+0x10/0x10
> [  107.129999]  genl_dumpit+0x11d/0x230
> [  107.130150]  netlink_dump+0x5b9/0xce0
> [  107.130301]  ? lockdep_hardirqs_on_prepare+0x253/0x430
> [  107.130503]  ? __pfx_netlink_dump+0x10/0x10
> [  107.130686]  ? kasan_save_track+0x10/0x40
> [  107.130849]  ? __kasan_kmalloc+0x9b/0xa0
> [  107.131009]  ? genl_start+0x675/0x970
> [  107.131162]  __netlink_dump_start+0x6fc/0x9f0
> [  107.131341]  genl_family_rcv_msg_dumpit+0x1bb/0x2d0
> [  107.131538]  ? __pfx_genl_family_rcv_msg_dumpit+0x10/0x10
> [  107.131754]  ? genl_op_from_small+0x2a/0x440
> [  107.131972]  ? cap_capable+0x1d0/0x240
> [  107.132127]  ? __pfx_genl_start+0x10/0x10
> [  107.132292]  ? __pfx_genl_dumpit+0x10/0x10
> [  107.132461]  ? __pfx_genl_done+0x10/0x10
> [  107.132645]  ? security_capable+0x9d/0xe0
>
> With the proposed patch applied, such a crash is not observed during
> long-term testing.

Maybe, but the patch is not good, I think I and Pablo gave feedback on this ?

Please trace __netlink_dump_start() content of control->module

gtp_genl_family.module should be set, and we should get it.

Otherwise, if the bug is in the core, we would need a dozen of 'work
arounds because it is better than nothing'

Thank you.

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

* Re: [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-02-09 19:21           ` Eric Dumazet
@ 2024-02-14 16:50             ` kovalev
  2024-02-15 20:32               ` Eric Dumazet
  0 siblings, 1 reply; 12+ messages in thread
From: kovalev @ 2024-02-14 16:50 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: pablo, laforge, davem, kuba, pabeni, osmocom-net-gprs, netdev,
	linux-kernel, nickel, oficerovas, dutyrok

09.02.2024 22:21, Eric Dumazet wrote:

> Maybe, but the patch is not good, I think I and Pablo gave feedback on this ?
>
> Please trace __netlink_dump_start() content of control->module
>
> gtp_genl_family.module should be set, and we should get it.
>
> Otherwise, if the bug is in the core, we would need a dozen of 'work
> arounds because it is better than nothing'
>
> Thank you.

Thanks.

I tracked the moment when the __netlink_dump_start() function was 
called, it turned out that in the gtp_init() initialization function 
before registering pernet subsystem (gtp_net_ops), therefore, outdated 
data is used, which leads to a crash.

The documentation says that ops structure must be assigned before 
registering a generic netlink family [1].

I have fixed and sent a new patch [2].

[1] 
https://elixir.bootlin.com/linux/v6.8-rc4/source/net/netlink/genetlink.c#L773

[2] 
https://lore.kernel.org/netdev/20240214162733.34214-1-kovalev@altlinux.org/T/#u

-- 
Regards,
Vasiliy Kovalev


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

* Re: [PATCH 1/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp()
  2024-02-14 16:50             ` kovalev
@ 2024-02-15 20:32               ` Eric Dumazet
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Dumazet @ 2024-02-15 20:32 UTC (permalink / raw)
  To: kovalev
  Cc: pablo, laforge, davem, kuba, pabeni, osmocom-net-gprs, netdev,
	linux-kernel, nickel, oficerovas, dutyrok

On Wed, Feb 14, 2024 at 5:50 PM <kovalev@altlinux.org> wrote:
>
> 09.02.2024 22:21, Eric Dumazet wrote:
>
> > Maybe, but the patch is not good, I think I and Pablo gave feedback on this ?
> >
> > Please trace __netlink_dump_start() content of control->module
> >
> > gtp_genl_family.module should be set, and we should get it.
> >
> > Otherwise, if the bug is in the core, we would need a dozen of 'work
> > arounds because it is better than nothing'
> >
> > Thank you.
>
> Thanks.
>
> I tracked the moment when the __netlink_dump_start() function was
> called, it turned out that in the gtp_init() initialization function
> before registering pernet subsystem (gtp_net_ops), therefore, outdated
> data is used, which leads to a crash.
>
> The documentation says that ops structure must be assigned before
> registering a generic netlink family [1].
>
> I have fixed and sent a new patch [2].
>
> [1]
> https://elixir.bootlin.com/linux/v6.8-rc4/source/net/netlink/genetlink.c#L773
>
> [2]
> https://lore.kernel.org/netdev/20240214162733.34214-1-kovalev@altlinux.org/T/#u
>

Excellent detective work, thanks a lot !

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

end of thread, other threads:[~2024-02-15 20:32 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-24 10:14 [PATCH 0/1] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp() kovalev
2024-01-24 10:14 ` [PATCH 1/1] " kovalev
2024-01-24 10:42   ` Eric Dumazet
2024-01-24 10:57   ` Eric Dumazet
2024-01-24 11:20     ` kovalev
2024-01-24 11:52       ` Eric Dumazet
2024-02-09 18:16         ` kovalev
2024-02-09 19:21           ` Eric Dumazet
2024-02-14 16:50             ` kovalev
2024-02-15 20:32               ` Eric Dumazet
2024-01-29 12:02       ` Pablo Neira Ayuso
2024-01-29 16:53         ` kovalev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).