add_subprog_and_kfunc() combines two operations with different ordering
requirements. Subprogram discovery must precede validation of func_info and
line_info, while kfunc descriptors are only needed by the verifier after its
initial program setup is complete.
Split the helper into add_subprogs() and add_kfuncs() so each operation can be
placed according to its actual dependencies. Keep both calls adjacent and in
their existing phase for now, and add short comments describing their roles.
No functional change is intended for valid programs.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Reviewed-by: Amery Hung <ameryhung@gmail.com>
Link: https://patch.msgid.link/20260808003938.3486067-3-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
BTF processing is split around subprogram discovery. The first phase gets
program BTF and imports func_info because a BTF-tagged exception callback
may not be referenced by any instruction. Subprogram discovery needs this
metadata to find it.
The later phase validates func_info and line_info against the complete
subprogram table and applies CO-RE relocations. This split breaks a real
dependency cycle rather than merely running the same checks early.
Rename bpf_check_btf_info_early() and check_btf_func_early() to preparation
names that reflect this role. Add short call-site comments to make the two
phases and their responsibilities clear.
No functional change is intended.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Reviewed-by: Amery Hung <ameryhung@gmail.com>
Link: https://patch.msgid.link/20260808003938.3486067-2-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Includes the following test cases:
- a test showing that zero extension flags do not propagate through
state pruning in the unpatched kernel.
- a 32-bit subregister consumed by MOV32 and ALU32 operations
(never zext'ed);
- a 64-bit MOV (never zext'ed);
- a narrow (32-bit) BPF_LDX load whose result is read as 64-bit;
- 32-bit atomic fetch_add and cmpxchg whose result is read as 64-bit;
- a CFG case where a 32-bit definition's upper half is used only on one
of two branches;
- no zext for dead registers;
- LD_ABS defines only lower 32 bits, hence needs zext when the result
is used as 64-bits;
- helper, kfunc and subprogram parameters are considered to use full
64 bits;
- a 32-bit subregister consumed by JMP32 (X/K) operations;
- a 32-bit subregister consumed by JMP (X/K) operations;
- a 64-bit register consumed by both JMP and JMP32 operations
(never zext'ed);
- ALU64 and address space cast operations on arena pointers;
- memory loads using BPF_PROBE_MEM instructions.
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260807-static-zext-v4-7-b6c270013c77@gmail.com
After the previous commit bpf_is_reg64() is only used in a context
where destination register's property is queried, and only for
instructions for which insn_def_regno() >= 0. Hence, simplify the
function by:
- removing unused parameters;
- removing code paths considering BPF_JMP{,32} instructions;
- streamlining the condition expressions.
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260807-static-zext-v4-6-b6c270013c77@gmail.com
As reported in the thread [1], the verifier's 32-bit operations zero
extension logic is broken. This logic is responsible for correct
semantics of 32-bit operations on s390 architecture.
According to BPF semantics, operation `w1 += 1` is supposed to zero
extend the upper half of the register `r1`. On s390 the JIT relies on
the verifier emitting explicit zero extension before such operations.
The verifier attempts to minimize the amount of zero extensions
inserted by tracking whether upper halves of the 64-bit registers are
ever used. Previously such tracking worked as follows:
- bpf_reg_state->subreg_def field was set by do_check_insn()
for each operation defining lower but not the upper halves
of the register.
- Whenever an operation reading the whole register was verified,
the verifier checked register's subreg_def and set
bpf_insn_aux_data->zext_dst flag as true via a call to
mark_insn_zext() function.
- After the verification was complete, a special pass
bpf_opt_subreg_zext_lo32_rnd_hi32() extended 32-bit operations
with bpf_insn_aux_data->zext_dst set as true by adding
explicit zero extension.
Note that the logic above relies on bpf_reg_state->subreg_def,
which is a property of a current verifier state.
Before the commit [2] two additional steps happened:
- The verifier tracked upper and lower register halves' liveness as
flags REG_LIVE_READ{32,64} in bpf_reg_state->live.
- The function propagate_liveness() called mark_insn_zext()
in order to transfer the knowledge about which registers have
their upper halves alive (and thus might require zero extension).
The commit [2] removed the two steps described above,
hence making possible a situation like below:
- The register's upper half is set and is used on some verification
path P1 and the register happens not to be marked as precise.
- The checkpoint C is created while processing some instruction
between register initialization and usage.
- On some other verification path P2 the register's upper half is not
initialized and that path ends hitting the checkpoint C.
- In such a case the register's initialization on path P2 would lack
zext_dst mark, making it possible for the program to inject
an arbitrary value in the register's upper half.
This commit replaces subreg_def based logic with computing zext_dst
statically, as a part of the bpf_compute_live_registers() analysis:
- The analysis now tracks usage of upper and lower halves of the
registers separately.
- If some instruction defines a 32-bit subregister, but not the whole
register, *and* the upper half of the register is alive after that
instruction, the instruction is marked as zext_dst.
There is one notable drop in precision: whenever a BPF subprogram is
called, all 64 bits of parameter registers are presumed to be used.
The assumption is that such a drop in precision would not inflict
a noticeable performance penalty.
[1] https://lore.kernel.org/bpf/CAGKGUv=sOuqQtA1Ub-5JXfA4FPosJFYKAQE4B79cK+P1erxqtg@mail.gmail.com/
[2] commit 107e169799 ("bpf: disable and remove registers chain based liveness")
Fixes: 107e169799 ("bpf: disable and remove registers chain based liveness")
Reported-by: Min-gyu Kim <gimm78064@gmail.com>
Reported-by: STAR Labs SG <info@starlabs.sg>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/CAGKGUv=sOuqQtA1Ub-5JXfA4FPosJFYKAQE4B79cK+P1erxqtg@mail.gmail.com/
Link: https://lore.kernel.org/bpf/20260807-static-zext-v4-5-b6c270013c77@gmail.com
Extend compute_live_registers() to track upper and lower register
halves' liveness separately. This is mostly straightforward:
- use/def masks are extended to track 2 bits per register;
- compute_insn_live_regs() is updated to properly track these
2 bits according to the instruction semantics.
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260807-static-zext-v4-4-b6c270013c77@gmail.com
bpf_do_misc_fixups() converts the following address space cast
instructions to 32-bit moves:
- cast from address space 1 (user) to address space 0 (kernel)
- cast from address space 0 (kernel) to address space 1 (user)
iff associated arena map has a BPF_F_NO_USER_CONV flag.
Extract a predicate detecting such instructions for use in the
following patches.
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260807-static-zext-v4-2-b6c270013c77@gmail.com
At the moment there are more callsites that want bpf_verbose_insn() to
not print a newline after the instruction, than callsites that want a
newline. Drop '\n' from disasm.c. Non-functional change.
The changes in bpftool are verified by writing a bpf program using a
variety of instructions and comparing `prog dump xlated` output in the
following modes: plain, opcodes, visual, visual opcodes. The output
before and after the changes is identical.
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Quentin Monnet <qmo@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260807-static-zext-v4-1-b6c270013c77@gmail.com
Pull BPF fixes from Daniel Borkmann:
- Fix BPF verifier to preserve full pointer state for commuted
scalar += pointer arithmetic (Yiyang Chen, Eduard Zingerman)
- Fix a use-after-free of request sockets in the BPF TCP iterator
batching (Jose Fernandez)
- Fix a use-after-free of sk_redir in the BPF sockmap send verdict
path (Chengfeng Ye)
- Fix a netns reference imbalance in the BPF conntrack kfuncs
(Chengfeng Ye)
- Fix bpf_get_fsverity_digest() dynptr assumptions and silent
digest truncation (Eric Biggers)
- Fix bpf_tcp_{gen,check}_syncookie to check sk_state before
sk_protocol to make sure it is a full socket (Luxiao Xu)
- Fix rqspinlock to reset the tail when preserving the queue
on deadlock (Kumar Kartikeya Dwivedi)
* tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
rqspinlock: Reset tail when preserving queue on deadlock
bpf: Check sk_state before sk_protocol in bpf_tcp_*_syncookie
fsverity: Fix silent truncation in bpf_get_fsverity_digest()
fsverity: Fix bpf_get_fsverity_digest() dynptr assumptions
bpf: tcp: Fix use-after-free in bpf_iter_tcp_established_batch()
bpf: Fix netns reference imbalance in conntrack kfuncs
bpf, sockmap: Fix sk_redir use-after-free in send verdict
selftests/bpf: Cover commuted pointer state propagation
bpf: Propagate untrusted pointer state in commuted arithmetic
bpf: Preserve pointer state for commuted arithmetic
bpf: Simplify sanitize_err() signature
Pull vkm fixes from Paolo Bonzini:
"s390:
- fix a lot of small bugs and races
x86:
- fix missing locking related to KVM_CAP_MOVE_ENC_CONTEXT_FROM
- warn on creating a new page table that is the child of an invalid
one, and limit damage before it's too late
- disable use of INVLPGA when NPT is enabled, because it doesn't seem
to flush TLBs correctly"
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (26 commits)
KVM: x86/mmu: WARN and clear role.invalid when creating a child shadow page
KVM: SVM: Serialize accesses to the owner and mirror list with separate lock
KVM: SVM: make svm_flush_tlb_gva do a full asid flush if NPT enabled
KVM: s390: Fix cleanup in kvm_s390_pv_create_cpu()
KVM: s390: Fix ordering when adding to SCA
KVM: s390: Return -EINTR if a signal is pending while faulting-in
KVM: s390: Free the mmu cache when kvm_arch_vcpu_create() fails
KVM: s390: ucontrol: Add missing locking around gmap_remove_child()
KVM: s390: cmma: Fix dirty tracking when removing memslot
KVM: s390: Fix race in __do_essa()
KVM: s390: Fix leaking of PGM_ADDRESSING to userspace
KVM: s390: ucontrol: Fix sca_clear_ext_call()
KVM: s390: Fix overclearing ESCA in case of error
KVM: s390: Fix kvm_s390_vcpu_unsetup_cmma()
KVM: s390: Do not free SCA if it was not allocated
KVM: s390: Fix unlikely NULL gmap dereference
s390/vfio_ccw: Implement a crw lock
s390/vfio_ccw: Selectively expand io_mutex
s390/vfio_ccw: Move cp cleanup out of not operational
s390/vfio_ccw: Cancel existing workqueues
...
Pull thermal control fixes from Rafael Wysocki:
"Revert three thermal core updates, two recent ones and one older.
The recent ones attempted to fix a design issue in the thermal core
and simplify code on top of that, but they made changes visible to
user space and made it unhappy.
The older one is a misguided code cleanup that introduced a
(potentially nasty) bug"
* tag 'thermal-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
Revert "thermal/drivers/hwmon: Cleanup coding style a bit"
Revert "thermal: hwmon: Register a hwmon device for each thermal zone"
Revert "thermal: hwmon: Use extra_groups for adding temperature attributes"
Pull sound fixes from Takashi Iwai:
"A collection of small fixes since the last pull request. More than
few, but an enough-manageable amount at this time.
USB-audio:
- UAF, OOB and such hardening fixes for USB-audio, usx2y and
us144mkii
- Mixer regression fixes for Logitech PRO X 2 LIGHTSPEED headset and
M-Audio Fast Track Ultra
HD-audio:
- Fix for an ACPI reference leak in TAS2781 HDA side-codec
ASoC:
- Fixes the default tables for Cirrus Logic codecs
- Fixes for invalid enum accesses for Qualcomm LPASS
- Error handling and robustness fixes for Intel SOF & Soundwire
- DMI quirks for a few AMD devices"
* tag 'sound-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (22 commits)
ALSA: usb-audio: Fix sticky mixer regressions on M-Audio Fast Track Ultra
ASoC: cs4265: sort the register default table
ASoC: cs35l45: sort the register default table
ASoC: cs35l41: sort the register default table
ASoC: amd: yc: Add DMI quirk for MSI Raider A18 HX A7VHG
ASoC: amd: yc: Add DMI quirk for Xiaomi RedmiBook 16 2025
ALSA: usx2y: bound the hwdep mmap fault offset
ALSA: usb-audio: fix OOB write on Type II inbound URBs
ALSA: us144mkii: re-anchor capture URBs on resubmission
ALSA: FCP: fix OOB write in fcp_meter_ctl_get()
MAINTAINERS: add SpacemiT K1/K3 I2S entry
ASoC: rt5645: Make the Kconfig symbol user selectable
ALSA: usb-audio: Add QUIRK_FLAG_MIXER_GET_CUR_BROKEN for Logitech PRO X 2 LIGHTSPEED
ALSA: hda/tas2781: fix ACPI reference handling
ASoC: codecs: lpass-wsa-macro: Fix enum kcontrol accesses
ASoC: codecs: lpass-tx-macro: Fix enum kcontrol accesses
ASoC: SOF: ipc4-pcm: Continue the pipeline trigger in case of IPC timeout
ASoC: amd: yc: Add DMI quirk for HP Victus Laptop 16-e1xxx
ASoC/soundwire: Intel: reset the PCMSyCM registers in hda_sdw_bpt_close
ASoC: SOF: sof-audio: Fix error path in sof_widget_setup_unlocked()
...
Add a verifier test that a BPF_LOAD_ACQ from a rdonly_untrusted_mem pointer
(PTR_TO_MEM | MEM_RDONLY | PTR_UNTRUSTED, obtained via bpf_rdonly_cast())
is rejected. Such a source requires BPF_PROBE_MEM fault protection which
is not applied to atomic loads; without the verifier fix the load is accepted
and would crash the kernel on a fault.
# LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t verifier_load_acquire
[...]
#621/1 verifier_load_acquire/load-acquire, 8-bit:OK
#621/2 verifier_load_acquire/load-acquire, 8-bit @unpriv:OK
#621/3 verifier_load_acquire/load-acquire, 16-bit:OK
#621/4 verifier_load_acquire/load-acquire, 16-bit @unpriv:OK
#621/5 verifier_load_acquire/load-acquire, 32-bit:OK
#621/6 verifier_load_acquire/load-acquire, 32-bit @unpriv:OK
#621/7 verifier_load_acquire/load-acquire, 64-bit:OK
#621/8 verifier_load_acquire/load-acquire, 64-bit @unpriv:OK
[...]
#621/19 verifier_load_acquire/load-acquire from rdonly_untrusted_mem pointer:OK
#621/20 verifier_load_acquire/load-acquire with invalid register R15:OK
#621/21 verifier_load_acquire/load-acquire with invalid register R15 @unpriv:OK
#621/22 verifier_load_acquire/load-acquire from pkt pointer:OK
#621/23 verifier_load_acquire/load-acquire from flow_keys pointer:OK
#621/24 verifier_load_acquire/load-acquire from sock pointer:OK
#621 verifier_load_acquire:OK
Summary: 1/24 PASSED, 0 SKIPPED, 0 FAILED
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260806201047.333389-6-daniel@iogearbox.net
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Add stream_arena_load_acquire_fault, which performs a load-acquire from an
unmapped arena address, next to the existing read and write fault tests.
The test covers both halves of the JIT bug that treated a load-acquire as
a store when populating its exception table entry:
- the fault has to be reported as a READ, and at the address held by
the source register, which __stderr() and test_address() check, and
- the destination register has to be cleared by the fault handler,
which the program checks by poisoning it before the load-acquire
and returning it, so __retval(0) fails if it is left untouched
Note, load-acquire is open coded since linux/filter.h cannot be included
alongside vmlinux.h.
# LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t stream_arena_fault_address
[...]
#462/1 stream_arena_fault_address/read_fault:OK
#462/2 stream_arena_fault_address/write_fault:OK
#462/3 stream_arena_fault_address/load_acquire_fault:OK
#462 stream_arena_fault_address:OK
Summary: 1/3 PASSED, 0 SKIPPED, 0 FAILED
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260806201047.333389-5-daniel@iogearbox.net
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Same problem as on x86-64: add_exception_handler() decides whether an
instruction is a load by its class, and a load-acquire is of BPF_STX
class even though it reads from src_reg into dst_reg. As a result ...
if (BPF_CLASS(insn->code) != BPF_LDX)
dst_reg = DONT_CLEAR;
... drops the register to clear, and ...
if (BPF_CLASS(insn->code) == BPF_LDX)
arena_reg = bpf2a64[insn->src_reg];
else
arena_reg = bpf2a64[insn->dst_reg];
... hands ex_handler_bpf() the value register instead of the address
register. A load-acquire from an arena pointer that faults on an
unmapped page is therefore reported as a WRITE at a bogus address,
and dst_reg keeps its previous value instead of being cleared to 0.
Note that emit_atomic_ld_st() already picks src_reg as the address
for BPF_LOAD_ACQ, so only the exception table metadata was out of sync
with the emitted access.
Same as on x86-64, use bpf_atomic_is_load_acq() so a load-acquire takes
the load path.
Fixes: 9bb12368d5 ("bpf, arm64: Support load-acquire and store-release instructions")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Puranjay Mohan <puranjay@kernel.org>
Link: https://lore.kernel.org/bpf/20260806201047.333389-4-daniel@iogearbox.net
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
A load-acquire from an arena pointer is converted to BPF_PROBE_ATOMIC and
gets an exception table entry, but the entry is filled in as if it were a
store, since populate_extable() decides based on instruction class alone
and a load-acquire is of BPF_STX class:
if (BPF_CLASS(insn->code) == BPF_LDX) {
arena_reg = reg2pt_regs[src_reg];
fixup_reg = reg2pt_regs[dst_reg];
} else {
arena_reg = reg2pt_regs[dst_reg];
fixup_reg = DONT_CLEAR;
}
For a load-acquire dst_reg holds the loaded value and src_reg holds the
address, so both assignments in the else branch are wrong. On a fault
over an unmapped arena page ex_handler_bpf() then:
- computes the reported address from the value register instead
of the address register
- reports the access as a WRITE, since it derives the direction
from fixup_reg == DONT_CLEAR
- leaves dst_reg untouched, so the program continues with a stale
value instead of the 0 that BPF_PROBE_* loads deliver
The access itself is emitted correctly, emit_atomic_ld_st_index() uses
src_reg as the address, so this is a broken probe contract and a wrong
diagnostic rather than a memory safety issue.
Use bpf_atomic_is_load_acq() helper so a load-acquire takes the load path.
Fixes: 5341c9a4d8 ("bpf, x86: Support load-acquire and store-release instructions")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260806201047.333389-3-daniel@iogearbox.net
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
A load-acquire is the only BPF_STX class instruction that reads from
src_reg into dst_reg, that is, it has the operand roles of a BPF_LDX.
JIT code which tells loads from stores apart by instruction class alone
has to special case it, for example when deciding which register holds
the faulting address and which one to clear from an exception handler.
riscv64 already does so, open coded as a bare insn->imm test. Add a
bpf_atomic_is_load_acq() helper and convert riscv64 over to it, so that
the x86-64 and arm64 JITs can use the same helper in subsequent patches.
Unlike bpf_atomic_is_load_store(), which presumes that its argument is
already known to be a BPF_ATOMIC instruction, the new helper is called
from code which still sees all instruction classes, so it checks class
and mode itself.
Also, move bpf_atomic_is_load_store() to filter.h next to BPF_ATOMIC_OP,
so that both helpers stay together. No functional change intended.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260806201047.333389-2-daniel@iogearbox.net
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
A BPF_LOAD_ACQ is not rewritten to a BPF_PROBE_MEM load by the verifier,
unlike a regular BPF_LDX, so the JIT emits a plain load with no exception
table entry and a fault panics the kernel instead of being handled.
Reject the source pointer types that a BPF_LDX would have had that fault
protection applied to, i.e. the ones bpf_convert_ctx_accesses() turns
into BPF_PROBE_MEM: a bare PTR_TO_BTF_ID, PTR_TO_BTF_ID | PTR_UNTRUSTED,
PTR_TO_BTF_ID | MEM_ALLOC | PTR_UNTRUSTED and PTR_TO_MEM | MEM_RDONLY |
PTR_UNTRUSTED.
This is reachable e.g. by loading ->mm out of a trusted task_struct
yields an untrusted pointer to mm_struct, and it is NULL for a kernel
thread:
[...]
SEC("tp_btf/sched_switch")
int BPF_PROG(demo, bool preempt, struct task_struct *prev,
struct task_struct *next)
{
struct mm_struct *mm = next->mm; /* untrusted */
out_ldx = (__u64)mm->pgd; /* BPF_LDX */
out_acq = load_acquire(&mm->pgd); /* BPF_LOAD_ACQ */
return 0;
}
[...]
Both dereference the same pointer, but only the BPF_LDX is protected
(x86-64 JIT, jump targets shown prog-relative):
[...]
; out_ldx = (__u64)mm->pgd;
17: movq $-10485760, %r10
1e: movq %rsi, %r11
21: addq $184, %r11
28: subq %r10, %r11
2b: movabsq $140737498841088, %r10
35: cmpq %r10, %r11
38: ja 0x3e <-- kernel addr?
3a: xorl %edi, %edi <-- no: dst = 0, skip the load
3c: jmp 0x45
3e: movq 184(%rsi), %rdi <-- yes: load + extable entry
[...]
; load_acquire(&mm->pgd)
53: movq %rsi, %rdi
56: movq 184(%rdi), %rax <-- no check, no extable entry
[...]
Note that BPF_PROBE_MEM is not visible in a bpftool xlated dump, as
bpf_insn_prepare_dump() rewrites it back to BPF_MEM.
A PTR_TRUSTED pointer is deliberately not on the list. Such a load is
not converted either, but it does not need to be, since the pointer is
guaranteed live, so load-acquire from it stays allowed.
The check is gated on BPF_LOAD_ACQ so that atomic RMW and store-release
error messages are unchanged; writes (RMW / store-release) to such
pointers are already rejected elsewhere, so only load-acquire needs this.
Fixes: 880442305a ("bpf: Introduce load-acquire and store-release instructions")
Reported-by: STAR Labs SG <info@starlabs.sg>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260806201047.333389-1-daniel@iogearbox.net
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
The recent fix for sticky mixer volumes caused regressions of M-audio
Fast Track Ultra device, where the mixer state is kept to the default
value.
Add the quirk entries to tolerate the broken mixer behavior. As the
device is known to work in the implicit feedback mode, explicitly
enable the implicit feedback mode, too.
Since there are two FTU models that are almost identical, both entries
are added in this patch (0763:2080 and 0763:2081).
Fixes: 86aa1ea1f1 ("ALSA: usb-audio: Do not expose sticky mixers")
Link: https://bugzilla.suse.com/show_bug.cgi?id=1273166
Link: https://patch.msgid.link/20260807083418.1712585-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Explicitly clear role.invalid when deriving a child shadow page's role from
its parent to harden against bugs elsewhere in KVM, as violating KVM's
invariant that invalid pages are NOT on the list of active MMU pages leads
to use-after-free due to __kvm_mmu_prepare_zap_page() using list_add()
instead of list_move() when processing an invalid shadow page, i.e. makes a
bad situation far worse.
Yell loudly if the parent is invalid, as it means KVM has missed a validity
check, i.e. KVM is attempting to map memory using an invalid/obsolete root,
but continue on as the child is otherwise still a valid shadow page.
==================================================================
BUG: KASAN: slab-use-after-free in __kvm_mmu_get_shadow_page+0x1817/0x1860 [kvm]
Write of size 8 at addr ff11000153dd1368 by task repro/853
CPU: 1 UID: 1000 PID: 853 Comm: repro Not tainted 7.2.0-rc2-3aec122bdcaf-next-vm #5 PREEMPT
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
Call Trace:
<TASK>
dump_stack_lvl+0x4b/0x70
print_report+0x153/0x49c
kasan_report+0xbc/0xf0
__kvm_mmu_get_shadow_page+0x1817/0x1860 [kvm]
mmu_alloc_root+0x141/0x320 [kvm]
kvm_mmu_load+0x612/0x20f0 [kvm]
kvm_arch_vcpu_ioctl_run+0x3dd5/0x6150 [kvm]
kvm_vcpu_ioctl+0x5e4/0x10d0 [kvm]
__x64_sys_ioctl+0x131/0x1b0
do_syscall_64+0x67/0x5f0
entry_SYSCALL_64_after_hwframe+0x4b/0x53
</TASK>
Allocated by task 853:
kasan_save_stack+0x20/0x40
kasan_save_track+0x14/0x30
__kasan_slab_alloc+0x5f/0x70
kmem_cache_alloc_noprof+0xfe/0x2e0
__kvm_mmu_topup_memory_cache+0x135/0x530 [kvm]
paging64_page_fault+0x318/0x1e30 [kvm]
kvm_mmu_do_page_fault+0x21d/0x630 [kvm]
kvm_mmu_page_fault+0x18c/0x17b0 [kvm]
kvm_arch_vcpu_ioctl_run+0x1f35/0x6150 [kvm]
kvm_vcpu_ioctl+0x5e4/0x10d0 [kvm]
__x64_sys_ioctl+0x131/0x1b0
do_syscall_64+0x67/0x5f0
entry_SYSCALL_64_after_hwframe+0x4b/0x53
Freed by task 853:
kasan_save_stack+0x20/0x40
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x43/0x70
kmem_cache_free+0xe2/0x400
kvm_mmu_commit_zap_page.part.0+0x1e2/0x310 [kvm]
kvm_mmu_free_roots+0x283/0x560 [kvm]
kvm_arch_vcpu_ioctl_run+0x33c8/0x6150 [kvm]
kvm_vcpu_ioctl+0x5e4/0x10d0 [kvm]
__x64_sys_ioctl+0x131/0x1b0
do_syscall_64+0x67/0x5f0
entry_SYSCALL_64_after_hwframe+0x4b/0x53
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Fixes: a770f6f28b ("KVM: MMU: Inherit a shadow page's guest level count from vcpu setup")
Cc: stable@vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Ihor Solodrai says:
====================
resolve_btfids: Implement BTF tags emission for kfuncs
BTF data for the kernel is generated through the following pipeline:
* DWARF is emitted by the compiler
* pahole reads in DWARF and produces BTF
* resolve_btfids makes kernel-specific btf2btf transformation and
patches .BTF_ids section
This is orchestrated by link-vmlinux.sh, gen-btf.sh and Makefile.btf
in ./scripts directory.
Historically kernel-specific BTF features were implemented in pahole,
and controlled by the feature flags. This requires kernel build
process to be aware of pahole version used for the build to set
correct runtime arguments for BTF encoding [1].
This is a burden which can be alleviated by splitting kernel/module
BTF generation in two stages:
1. Generic BTF generation from the kernel source code.
2. Kernel-specific BTF modifications to support various BPF features.
So far both stages were fused in pahole's BTF encoding. By moving
stage (2) in-tree, the dependency of kernel build on pahole can become
much more loose.
resolve_btfids is already responsible for a few kernel-specific BTF
modifications:
* .BTF.base generation for modules [2]
* BTF sorting [3]
* KF_IMPLICIT_ARGS support [4]
This series completes the migration by emitting BTF kfunc annotations
in-tree: the "bpf_kfunc" and "bpf_fastcall" decl tags and the arena
"address_space(1)" type attribute, dropping the corresponding pahole
feature flags.
The three annotations depend on two pahole feature flags:
"decl_tag_kfuncs" and "attributes". Since emission is unconditional,
each flag has to be dropped in the same commit as the emission that
replaces it.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/Makefile.btf?h=v7.1-rc5
[2] https://docs.kernel.org/bpf/btf.html#btf-base-section
[3] https://lore.kernel.org/bpf/20260109130003.3313716-4-dolinux.peng@gmail.com/
[4] https://lore.kernel.org/bpf/20260120222638.3976562-1-ihor.solodrai@linux.dev/
[5] https://lore.kernel.org/bpf/20260722233518.778854-1-ihor.solodrai@linux.dev/
[6] https://lore.kernel.org/bpf/20260617210619.1562858-1-ihor.solodrai@linux.dev/
---
v2->v3:
* Refactoring in patch #2 (Eduard)
* restructure add_arena_tagged_proto() such that first we copy the
func proto and then update param types in place
* push error messages down to arena_tag_ptr()
* introduce is_arena_arg() helper
* Docs cleanup in patch #6 (Eduard)
* Add stats in commit message for patch #1
v2: https://lore.kernel.org/bpf/20260805230648.2354989-1-ihor.solodrai@linux.dev/
v1->v2:
* The bottom part of v1 has already been landed [5][6].
* New patch #1: run btf__dedup() in finalize_btf().
* Drop the "ensure" pattern. Emission is unconditional; kbuild owns
the pahole flags, so assume input BTF is not already tagged.
* Each pahole flag is now dropped in the same commit as the emission
that replaces it.
* Fail hard with an error on invalid kfunc declarations such as an
arena flag naming a missing argument or a non-pointer type.
* Various cleanups and nits (Andrii, Emil, Jiri, Sashiko).
v1: https://lore.kernel.org/bpf/20260601221805.821394-1-ihor.solodrai@linux.dev/
---
====================
Link: https://patch.msgid.link/20260807032029.78092-1-ihor.solodrai@linux.dev
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
For kfuncs flagged with KF_ARENA_RET, KF_ARENA_ARG1 or KF_ARENA_ARG2,
the address_space(1) attribute (a type tag with kflag=1) must be
emitted for the corresponding type in BTF. This was previously done by
pahole via the "attributes" BTF feature [1].
Implement the emission of the arena attributes in resolve_btfids: for
flagged kfuncs create a new function prototype with updated BTF types.
The original proto may be shared with sibling FUNCs, so it is not
modified in place.
Emission is unconditional: kbuild controls the pahole flags, so the
input BTF is expected to not have these attributes. Invalid
declarations are reported as errors.
Drop the "attributes" pahole feature from scripts/Makefile.btf
resolve_btfids now emits them for all supported pahole versions.
[1] https://lore.kernel.org/dwarves/20250228194654.1022535-1-ihor.solodrai@linux.dev/
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://patch.msgid.link/20260807032029.78092-3-ihor.solodrai@linux.dev
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
btf2btf() adds new types to the BTF: the KF_IMPLICIT_ARGS transform
synthesizes an _impl FUNC together with its FUNC_PROTO and copies of the
kfunc's decl tags. Nothing deduplicates them afterwards. pahole runs
btf__dedup() on its own output, but that happens before resolve_btfids
sees the BTF, so any type the tool itself creates is emitted as-is, even
when a structurally identical type is already present.
Call btf__dedup() at the start of finalize_btf(), so that base
distillation and the by-name sort both operate on the canonical set of
types.
On an x86_64 build with the BPF selftests config this removes 17
duplicate FUNC_PROTOs from vmlinux BTF.
The dedup call increases runtime of resolve_btfids on vmlinux by 30-40%.
The performance hit is an acceptable cost to keep kernel BTF deduped [1].
[1] https://lore.kernel.org/bpf/986e6f4e-4b51-4440-a37c-9624906d7370@linux.dev/
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://patch.msgid.link/20260807032029.78092-2-ihor.solodrai@linux.dev
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Pull MM fixes from Andrew Morton:
"17 hotfixes. 15 are cc:stable. 16 are for MM.
There's a patch series from Lorenzo "mm: fix UAF caused by race
between ptdump and vmap pgtable freeing" which addresses a quite old
bug in the ptdump code.
And another series also from Lorenzo which fixes a four year old bug
in the huge_zero_folio handling.
A series from SJ fixes a few possible divide-by-zero issues which
Sashiko sniffed out. And a series which fixes handling of the
commit_inputs parameters.
The remainder are singletons, please see their changelogs for details"
* tag 'mm-hotfixes-stable-2026-08-06-18-44' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
mm/damon: adjust isolated pages stat for DAMOS_MIGRATE_{HOT,COLD}
mm/damon/ops-common: putback folios on invalid migrate nid
mm/huge_memory: initialise workingset state before folio split
mm/page_table_check: skip special zero mappings
mm/damon/lru_sort: skip damon_call() if ctx has not started
mm/damon/reclaim: skip damon_call() if ctx has not started
mm/damon/lru_sort: error out for >10000 active_mem_bp
samples/damon/mtier: error out for zero quota goal target values
mailmap: map old addresses to Danila Tikhonov
mm/huge_memory: separate out CONFIG_PERSISTENT_HUGE_ZERO_FOLIO logic
mm/huge_memory: fix huge_zero_pfn race
MAINTAINERS: update address for Brendan Jackman
mm/filemap: __filemap_add_folio() restore index before retrying
microblaze: restore the page alignment of swapper_pg_dir
arm64: remove redundant concurrent ptdump UAF mitigation
mm/ptdump: always stabilise against page table freeing using init_mm
mm/vmalloc: acquire init_mm lock on huge vmap to avoid ptdump UAF
Pull smb server fixes from Steve French:
- Reject Pattern_V1 payloads when Pattern_V1 support was not
negotiated
- Validate compression transform flags and chained mode before
allocating the decompression buffer
- Enforce the pre-authentication PDU size limit before allocating
the decompression buffer, preventing compressed requests from
bypassing the limit
* tag 'v7.2-rc6-smb3-server-fixes' of git://git.samba.org/ksmbd:
ksmbd: apply the pre-authentication PDU limit when decompressing
ksmbd: validate compression Flags before kvmalloc
smb: compress: reject Pattern_V1 when not negotiated
Currently, the destruction of the waiter queue is suppressed for
rqspinlock in cases where a deadlock is detected. Deadlock checks happen
relatively frequently (on entry for AA, within 1ms for ABBA), and waiter
threads may not be involved in locking scenarios involving deadlocks.
Thus, it is useful to not flush the queue and let other waiters take a
stab at acquiring the lock after we detect a deadlock and exit.
However, we need to follow the same logic as what we did previously for
the waitq_timeout label: reset the tail, and if we cannot, signal the
next waiter appropriately. In case of deadlocks, this signal would just
mark the MCS node as unlocked, and in case of timeouts, it would signal
RES_TIMEOUT_VAL. The difference thus is in the value propagated, which
decides whether the queue remains active or gets flushed.
Not doing the tail reset, and waiting for the next waiter can lead to
cases where we are the final waiter, and thus no next waiter arrives,
leading to intermittent stalls in this path. Once the next waiter does
join, we will be unblocked. In the theoretical case when the next waiter
never joins, we risk stalling indefinitely.
This can only happen for ABBA deadlocks, since entry into the wait queue
is guarded with AA checks. A precise sequence of executions leading up
to this scenario can be:
CPU 0 holds lock A.
CPU 1 holds lock B.
CPU 2 attempts lock B, becomes the pending waiter for B.
CPU 0 attempts lock B. B has locked+pending bits set, thus CPU 0 queues.
CPU 1 attempts lock A.
CPU 0 detects an ABBA deadlock.
Once deadlock detection happens for CPU 0, it will sit waiting for the
next waiter in the queue to populate node->next, which will experience
delays until such a waiter arrives.
Fix this by adjusting the logic for the check for deadlocks preceding
the waitq_timeout label. It would make sense to consolidate code for
both cases and use 'ret' to distinguish the value being propagated, but
that is left as an exercise for a future refactoring task to avoid diff
noise in this patch.
Fixes: 7bd6e5ce5b ("rqspinlock: Disable queue destruction for deadlocks")
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://patch.msgid.link/20260802021759.1139457-1-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Pull smb client fixes from Steve French:
- Fix potential use after free in cifs_try_adding_channels
- Fix SMB1 large directory enumeration
- Minor debug improvement (show compress mount option)
* tag 'v7.2-rc6-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
smb: client: fix SMB1 TRANS2 multi-response truncation in SendReceive()
smb: client: Fix use-after-free in cifs_try_adding_channels()
smb/client: show compress mount option
Pull Btrfs Fixes 2: Electric Boogaloo from David Sterba:
"This brings back the fixup worker infrastructure.
It's a mechanism to detect pages/folios that are marked dirty without
filesystem knowledge and require COW fixup. The consequence of not
doing so is silent data loss.
The first patch covers the scenarios in detail, also reflecting folio
API port and subpage block size support added in recent years. The
original fixup worker was only for pages.
The patch is relatively big, half of the code is debugging and support
code, the rest is the core design around the detection and fix.
The second patch handles an unlikely case when there's work left
during unmount"
* tag 'for-7.2-rc6-fixup-worker-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: flush the fixup workers during close_ctree
btrfs: trigger cow fixup via dirty_folio()
Pull btrfs fixes from David Sterba:
- fix leak in encoded ioctl write
- disable large folios on systems with highmem
- disable block size > page size when there's no transparent hugepage
support (under experimental config)
- reject compressed inline extents without valid LZO headers
- properly initialize cached inode mapping (if block size > page size)
* tag 'for-7.2-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: initialize inode mapping flags for cached inodes
btrfs: disable bs > ps support if no transparent hugepage support
btrfs: fix memory leak in btrfs_do_encoded_write()
btrfs: lzo: reject inline extents without valid headers
btrfs: disable large folios for systems with highmem
Pull networking fixes from Jakub Kicinski:
"Including fixes from netfilter.
Looks like our attempt to keep the PRs smaller have only prevented
this one from getting even bigger. In the last 9 days there were
405 postings explicitly tagged with [PATCH net], vs 687 with [PATCH
net-next]. 37% of posted patches being fixes is pretty crazy, and
that's likely undercounting because LLM "researchers" more often post
fixes without knowing to tag the patches for specific trees. I don't
have historic data.
In any case, we keep adjusting the criteria. The next PR will be
smaller.
Current release - regressions:
- net: defer netdev KOBJ_ADD uevent until the device is published,
previously rtnl_lock would serialize the accesses vs publishing
- net: explicitly cancel work to avoid races with ref tracker exit
- qrtr: ns: raise lookup limit to 128
- eth: hns3: fix speed configuration residue after driver reload
Previous releases - regressions:
- tcp: do not change rcv_ssthresh in tcp_measure_rcv_mss(), regressed
flows with MSS and scaling_ratio variability
- Revert "net: thunderbolt: Enable end-to-end flow control also in
transmit", broke some platforms (no packets coming thru)
- eth: stmmac: resume PHY before hardware setup when opening the
interface
Previous releases - always broken:
- another pile of fixes for less common protocols (SCTP, TLS, SMC
etc.)
- close a couple of AF_PACKET bugs and ways it can build skbs
problematic for the rest of the stack
- bridge: mrp: fix uninitialised bytes on the wire
- net: devmem: prevent net-iov / page mixing, avoid crashes
- eth: atlantic: free RX pages of consumed but not refilled buffers"
* tag 'net-7.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (116 commits)
igc: fix netdev not re-attached after resume if interface is down
tls: don't abort the connection on signal-interrupted sends
net: avoid theoretical races with ref drain
net: Defer netdev KOBJ_ADD uevent until the device is published
MAINTAINERS: dpll: zl3073x: replace Prathosh Satish with Min Li
sctp: clear control chunk transport if it is being removed
net/atm: fix slab-out-of-bounds read in vcc_setsockopt()
s390/ism: Fix UAF of sba and ieq during ism_dev_exit()
packet: use consistent hard_header_len in TX_RING send path
packet: use consistent hard_header_len in non-ring send paths
net: remove CAP_SYS_RAWIO zero-padding in dev_validate_header
bnge: Fix resource leak in bnge_init_nic() error path
ptp: ocp: Fix board ID over-read
tls: rx: restore msg_iter before TLS 1.3 optimistic retry
selftests: tls: add a test for splicing onto a full plaintext record
tls: don't leave a full plaintext sk_msg ring unpushed
xdp: reject clones that overrun skb_shared_info tailroom
mptcp: reclaim forward-allocated memory on RX path errors
mptcp: fastopen: only mark MPTFO subflows with SYN data
mptcp: pm: fix memory leak from alloc-during-teardown race
...
__igc_resume() calls netif_device_attach() only inside the
netif_running() branch, so an interface that was down during suspend
is never re-attached on resume. It then stays in the not-present state
that __igc_shutdown() set via netif_device_detach(): ethtool reports
ENODEV and every attempt to bring the interface up fails the
netif_device_present() check in __dev_open() with -ENODEV, silently,
since __igc_resume() returns 0. Only reloading the driver recovers the
device.
This is easy to hit in practice because NetworkManager brings managed
interfaces down before sleep unless Wake-on-LAN is configured, making
the adapter unusable after every suspend/resume cycle with WoL
disabled.
Re-attach the netdev on every successful resume, as igb and e1000e do.
Fixes: 6f31d6b643 ("igc: Refactor runtime power management flow")
Cc: stable@vger.kernel.org
Signed-off-by: Philipp David <pd-lkml@3b.pm>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Dima Ruinskiy <dima.ruinskiy@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Link: https://patch.msgid.link/20260804222205.1580328-11-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
When a signal interrupts a blocking send, tls_tx_records() treats the
resulting -ERESTARTSYS as a transmission failure and marks the socket
errored via tls_err_abort() with the raw error code. Later syscalls
return the kernel-internal errno 512 (ERESTARTSYS) to userspace, as the
signal it stems from is no longer pending during syscall exit and thus
never translated.
An interrupted send is not a connection error: the partially sent record
stays queued and is resent later. Interrupt error codes are therefore
excluded from the abort in the same way as -EAGAIN.
Fixes: b341ca51d2 ("tls: Fix tls_sw_sendmsg error handling")
Signed-off-by: Maximilian Immanuel Brandtner <maxbr@linux.ibm.com>
Link: https://patch.msgid.link/20260805063109.1772314-1-maxbr@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Technically, it's illegal to take a ref on a netdev just because
we have a pointer on which we already hold a ref, with no other
protection. This is because our simple per-cpu refcount
implementation cannot atomically read the count.
Let's make sure we cancel outstanding work and never queue more
work for a device we know is dead. This way taking a ref on
a dev we know is on the netdev_work_list is always going to be safe.
Jiangshan Yi reports that the issues is caught by ref tracker infra
leading to a warning:
WARNING: lib/ref_tracker.c:322 at ref_tracker_free
WARNING: lib/ref_tracker.c:246 at ref_tracker_dir_exit
Reported-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Link: https://lore.kernel.org/20260731035135.3917308-2-yijiangshan@kylinos.cn
Fixes: 12c765be84 ("net: turn the rx_mode work into a generic netdev_work facility")
Link: https://patch.msgid.link/20260806022821.2079945-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
netdev_register_kobject() calls device_add(), which emits KOBJ_ADD and
wakes udev, but register_netdevice() only makes the device findable by
name later, in list_netdevice(). A udev worker that reacts to the uevent
can therefore run against a device that no lookup can find yet.
This used to be harmless because the ethtool ioctl took the rtnl_lock
when looking the device up, and register_netdevice() runs under rtnl, so
the worker simply blocked until registration finished. The commit in the
fixes tag moved the lookup out from under rtnl for ops-locked drivers.
Now there is a short window in register_netdevice() between
netdev_register_kobject() until list_netdevice() when the device is not
findable by name.
This was reproduced with the mlx5 driver on a kernel with KASAN enabled
during devlink reload: systemd-udevd's net_driver builtin gets -ENODEV
from ETHTOOL_GDRVINFO, which was preventing interface renaming.
Suppress the uevent in netdev_register_kobject() and emit it from
register_netdevice() next to rtmsg_ifinfo(). This is the last point in
register_netdevice() where no error can happen, so only fully registered
devices are announced: the registration error paths never reach it, and
the device_del() that unwinds them stays silent as well, leaving
userspace with neither an add nor a remove.
Fixes: f994752b11 ("net: ethtool: optionally skip rtnl_lock on IOCTL path")
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Shahar Shitrit <shshitrit@nvidia.com>
Link: https://patch.msgid.link/20260806080758.2039586-2-dtatulea@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
sctp_make_heartbeat_ack() caches the destination transport in
chunk->transport without taking a reference. When src_out_of_asoc_ok is
enabled, the HEARTBEAT ACK may remain queued on control_chunk_list instead
of being transmitted immediately.
If the peer transport is removed while the chunk is still queued,
sctp_assoc_rm_peer() drops the transport and schedules it for RCU freeing,
but only clears cached transport pointers in out_chunk_list. The queued
control chunk therefore retains a dangling transport pointer.
Once an ASCONF_ACK clears the suppression and the queued control chunk is
transmitted, SCTP dereferences the stale transport pointer, leading to a
use-after-free.
Fix this by also clearing chunk->transport for queued control chunks in
control_chunk_list when removing the transport.
Fixes: 8a07eb0a50 ("sctp: Add ASCONF operation on the single-homed host")
Reported-by: Daniele Linguaglossa <danielelinguaglossa@gmail.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/7e1168cb722132152a29d47e5eafaeac4a3bf6f3.1785943120.git.lucien.xin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
vcc_setsockopt() contained an ineffective optlen check:
if (__SO_LEVEL_MATCH(optname, level) && optlen != __SO_SIZE(optname))
return -EINVAL;
If __SO_LEVEL_MATCH(optname, level) evaluated to false (e.g. if the caller
passed a mismatched level), the length check optlen != __SO_SIZE(optname)
was short-circuited and bypassed. Execution then fell through to switch(optname),
calling copy_from_sockptr() assuming optval contained sufficient space.
Furthermore, even if level matched, a cgroup BPF setsockopt filter could shrink
optlen after entry. Because copy_from_sockptr() on kernel pointers uses memcpy(),
this leads to a KASAN slab-out-of-bounds read when optlen is smaller than the
expected structure size.
Fix this by using copy_safe_from_sockptr(), which unconditionally validates
that optlen is at least the expected size before copying. Also change the local
'value' variable type from 'unsigned long' to 'int' so that SO_SETCLP matches
its sizeof(int) ABI encoding on 64-bit systems.
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Reported-by: syzbot+53ecc09fb81df10ef4de@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=53ecc09fb81df10ef4de
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260805131508.3227331-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
A ism interrupt handler can be active in parallel with ism_dev_exit(),
accessing freed data structures.
No new interrupts will be generated after unregister_ieq(). Drain ongoing
interrupt handlers by free_irq(), before freeing ism data structures.
Fixes: 684b89bc39 ("s390/ism: add device driver for internal shared memory")
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Link: https://patch.msgid.link/20260805131043.954639-1-wintera@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Qihang Tang says:
====================
net: fix hard_header_len races in packet send paths
The packet socket TX paths read dev->hard_header_len independently for
skb allocation and header construction. Concurrent netdevice
reconfiguration (e.g. bonding device type changes) can change this value
in between, leading to mismatched headroom and copy length, and in the
SOCK_RAW case to out-of-bounds writes.
Patch 1 removes the CAP_SYS_RAWIO zero-padding branch in
dev_validate_header(). That branch sizes a memset against the live
dev->hard_header_len while operating on an skb whose headroom was
allocated from an earlier hard_header_len read, so a concurrent increase
can write past the reserved buffer. Removing it first keeps the later
snapshot fixes bisect-safe: they do not replace an earlier skb_under_panic
with a silent overwrite.
Patches 2 and 3 snapshot hard_header_len once per send and use it
consistently for allocation and construction, in the non-ring and TX_RING
paths respectively. The separate SOCK_DGRAM consistency problem between
hard_header_len and header_ops->create remains out of scope, as noted in
the commit messages.
====================
Link: https://patch.msgid.link/20260805125729.19220-1-q.h.hack.winter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tpacket_snd() reads dev->hard_header_len independently for skb
allocation and header construction in tpacket_fill_skb(). Concurrent
netdevice reconfiguration can therefore make the reserved headroom
smaller than the amount later pushed, or make copylen - hard_header_len
negative.
Snapshot hard_header_len once before processing ring frames and use it
for the frame limit, headroom allocation, copy length, and skb
construction. Pass the snapshot to tpacket_fill_skb().
The separate SOCK_DGRAM consistency problem between hard_header_len and
header_ops->create is not addressed here.
Fixes: 69e3c75f4d ("net: TX_RING and packet mmap")
Cc: stable@vger.kernel.org
Signed-off-by: Qihang Tang <q.h.hack.winter@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260805125729.19220-4-q.h.hack.winter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
packet_snd() reads dev->hard_header_len multiple times while allocating
and constructing an skb. Device reconfiguration can change this value
concurrently, for example through bonding device type changes.
For SOCK_RAW, packet_snd() can save a larger value in reserve and later
allocate headroom using a smaller value. Moving skb->data back by reserve
then places it before skb->head, and the following copy from userspace can
attempt an out-of-bounds write.
packet_sendmsg_spkt() has the same issue because it calculates its
reservation and header offset from separate reads before dropping the RCU
read lock to allocate the skb.
Add LL_RESERVED_SPACE_EX() for callers that already saved a header length.
Read hard_header_len once in packet_snd() and use it for allocation and
construction. In packet_sendmsg_spkt(), preserve the allocation-time value
through the device lookup retry.
The separate SOCK_DGRAM consistency problem between hard_header_len and
header_ops->create is not addressed here.
Fixes: b84bbaf7a6 ("packet: in packet_snd start writing at link layer allocation")
Cc: stable@vger.kernel.org
Signed-off-by: Qihang Tang <q.h.hack.winter@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260805125729.19220-3-q.h.hack.winter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
dev_validate_header() reads dev->hard_header_len directly when
zero-padding short link layer headers for CAP_SYS_RAWIO holders:
if (capable(CAP_SYS_RAWIO)) {
memset(ll_header + len, 0, dev->hard_header_len - len);
return true;
}
Packet send paths call dev_validate_header() on skbs whose headroom was
allocated from an earlier hard_header_len read. If the device is
reconfigured so that dev->hard_header_len increases before validation,
the memset writes past the reserved buffer, an out-of-bounds write.
This out-of-bounds write is masked in some SOCK_RAW paths today because
the same concurrent increase can first make skb_push() exceed the
reserved headroom and trigger skb_under_panic(). Remove the zero-padding
branch before making those hard_header_len reads consistent, so the
snapshot fixes do not turn a loud panic into a silent overwrite.
This path is only reached for variable length L2 protocols, where
len < hard_header_len but len >= min_header_len. No remaining in-tree
variable length L2 protocol implements header_ops->validate, and the
CAP_SYS_RAWIO bypass that zero-pads and accepts short headers has no
real value beyond allowing testing of intentionally malformed input.
Drop the CAP_SYS_RAWIO branch. The remaining reads of
dev->hard_header_len in dev_validate_header() are comparisons only and
have no memory safety impact.
Suggested-by: Willem de Bruijn <willemb@google.com>
Fixes: 2793a23aac ("net: validate variable length ll headers")
Cc: stable@vger.kernel.org
Signed-off-by: Qihang Tang <q.h.hack.winter@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260805125729.19220-2-q.h.hack.winter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>