CVE: CVE-2025-40041
Published: 2025-10-28
Description: In the Linux kernel, the following vulnerability has been resolved:

LoongArch: BPF: Sign-extend struct ops return values properly

The ns_bpf_qdisc selftest triggers a kernel panic:

  Oops[#1]:
  CPU 0 Unable to handle kernel paging request at virtual address[PII_REDACTED]741d58, era ==[PII_REDACTED]1b5ac0, ra ==[PII_REDACTED]1b5aa4
  CPU: 0 UID: 0 PID: 449 Comm: test_progs Tainted: G           OE       6.16.0+ #3 PREEMPT(full)
  Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
  Hardware name: QEMU QEMU Virtual Machine, BIOS unknown 2/2/2022
  pc[PII_REDACTED]1b5ac0 ra[PII_REDACTED]1b5aa4 tp[PII_REDACTED]6b8000 sp[PII_REDACTED]6bb600
  a0[PII_REDACTED]741ce8 a1 [PII_REDACTED] a2[PII_REDACTED]6bb5c0 a3 [PII_REDACTED]
  a4[PII_REDACTED]4c4620 a5[PII_REDACTED]741ce8 a6 [PII_REDACTED] a7 [PII_REDACTED]
  t0 [PII_REDACTED] t1 [PII_REDACTED] t2[PII_REDACTED]d24d30 t3 [PII_REDACTED]
  t4 4f2317da8a7e08c4 t5 fffffefffc002f00 t6[PII_REDACTED]4c4620 t7 ffffffffc61c5b3d
  t8 [PII_REDACTED] u0 [PII_REDACTED] s9 [PII_REDACTED] s0[PII_REDACTED]5bc800
  s1 [PII_REDACTED] s2[PII_REDACTED]97c400 s3 [PII_REDACTED] s4[PII_REDACTED]5bc880
  s5[PII_REDACTED]5bc8f0 s6 [PII_REDACTED] s7[PII_REDACTED]741ce8 s8 [PII_REDACTED]
     ra:[PII_REDACTED]1b5aa4 __qdisc_run+0xac/0x8d8
    ERA:[PII_REDACTED]1b5ac0 __qdisc_run+0xc8/0x8d8
   CRMD: 000000b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE)
   PRMD: 00000004 (PPLV0 +PIE -PWE)
   EUEN: 00000007 (+FPE +SXE +ASXE -BTE)
   ECFG: 00071c1d (LIE=0,2-4,10-12 VS=7)
  ESTAT: 00010000 [PIL] (IS= ECode=1 EsubCode=0)
   BADV:[PII_REDACTED]741d58
   PRID: 0014c010 (Loongson-64bit, Loongson-3A5000)
  Modules linked in: bpf_testmod(OE) [last unloaded: bpf_testmod(OE)]
  Process test_progs (pid: 449, threadinfo=000000009af02b3a, task=00000000e9ba4956)
  Stack : [PII_REDACTED][PII_REDACTED]5bc8ac[PII_REDACTED]9524a8[PII_REDACTED]741ce8
         [PII_REDACTED]5bc800 [PII_REDACTED][PII_REDACTED]5bc8ac [PII_REDACTED]
         [PII_REDACTED]97c[PII_REDACTED]08694a000 [PII_REDACTED][PII_REDACTED]b59000
         [PII_REDACTED]5bc[PII_REDACTED]100741ce8 [PII_REDACTED][PII_REDACTED]13000c
          [PII_REDACTED][PII_REDACTED]094d4c fffffff400676208 [PII_REDACTED]
         [PII_REDACTED]b59[PII_REDACTED]08694a[PII_REDACTED]086bf0dc0[PII_REDACTED]b59000
         [PII_REDACTED]bf0d68 [PII_REDACTED][PII_REDACTED]5be788 [PII_REDACTED]
         [PII_REDACTED]bf0f98 [PII_REDACTED] [PII_REDACTED] [PII_REDACTED]
          [PII_REDACTED][PII_REDACTED]be6c40 [PII_REDACTED] [PII_REDACTED]
          [PII_REDACTED] 4f2317da8a7e08c4 [PII_REDACTED] 4f2317da8a7e08c4
          ...
  Call Trace:
  [<[PII_REDACTED]1b5ac0>] __qdisc_run+0xc8/0x8d8
  [<[PII_REDACTED]>] __dev_queue_xmit+0x578/0x10f0
  [<[PII_REDACTED]3701c0>] ip6_finish_output2+0x2f0/0x950
  [<[PII_REDACTED]374bc8>] ip6_finish_output+0x2b8/0x448
  [<[PII_REDACTED]370b24>] ip6_xmit+0x304/0x858
  [<[PII_REDACTED]3c4438>] inet6_csk_xmit+0x100/0x170
  [<[PII_REDACTED]2b32f0>] __tcp_transmit_skb+0x490/0xdd0
  [<[PII_REDACTED]2b47fc>] tcp_connect+0xbcc/0x1168
  [<[PII_REDACTED]3b9088>] tcp_v6_connect+0x580/0x8a0
  [<[PII_REDACTED]2e7738>] __inet_stream_connect+0x170/0x480
  [<[PII_REDACTED]2e7a98>] inet_stream_connect+0x50/0x88
  [<[PII_REDACTED]0f2814>] __sys_connect+0xe4/0x110
  [<[PII_REDACTED]0f2858>] sys_connect+0x18/0x28
  [<[PII_REDACTED]520c94>] do_syscall+0x94/0x1a0
  [<[PII_REDACTED]df1fb8>] handle_syscall+0xb8/0x158

  Code: 4001ad80  2400873f  2400832d <240073cc> 001137ff  001133ff  6407b41f  001503cc  0280041d

  ---[ end trace [PII_REDACTED] ]---

The bpf_fifo_dequeue prog returns a skb which is a pointer. The pointer
is treated as a 32bit value and sign extend to 64bit in epilogue. This
behavior is right for most bpf prog types but wrong for struct ops which
requires LoongArch ABI.

So let's sign extend struct ops return values according to the LoongArch
ABI ([1]) and return value spec in function model.

[1]: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html
References: https://git.kernel.org/stable/c/8b51b11b3d81c1ed48a52f87da9256d737b723a0; https://git.kernel.org/stable/c/9f3169bb3c2967166b4f4433cf152a84f3eb95d0