]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Fix stack slot index in nospec checks
authorNuoqi Gui <gnq25@mails.tsinghua.edu.cn>
Wed, 17 Jun 2026 17:50:26 +0000 (01:50 +0800)
committerAlexei Starovoitov <ast@kernel.org>
Mon, 22 Jun 2026 00:51:58 +0000 (17:51 -0700)
check_stack_write_fixed_off() computes the byte slot for a fixed-offset
stack write as -off - 1, and records each written byte in slot_type[] with
(slot - i) % BPF_REG_SIZE.

The Spectre v4 sanitization pre-check uses slot_type[i] instead. For a
4-byte write at fp-8 after the lower half of fp-8 has been zeroed, the
pre-check scans bytes 0..3 and sees STACK_ZERO while the actual write updates
bytes 7..4. That can leave the second half-slot write without nospec_result
even though the bytes being overwritten still require sanitization.

Use the same slot index in the sanitization pre-check that the write path uses
when updating slot_type[].

Fixes: 2039f26f3aca ("bpf: Fix leakage due to insufficient speculative store bypass mitigation")
Acked-by: Luis Gerhorst <luis.gerhorst@fau.de>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
Link: https://lore.kernel.org/r/20260618-f01-11-stack-nospec-slot-index-v3-1-780297041721@mails.tsinghua.edu.cn
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index 2abc79dbf281c21b477ceb09dbb6f14c9e187c6b..50e80dbbc1784667eb5ade4c662f6640abe54bde 100644 (file)
@@ -3479,7 +3479,8 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
                bool sanitize = reg && is_spillable_regtype(reg->type);
 
                for (i = 0; i < size; i++) {
-                       u8 type = state->stack[spi].slot_type[i];
+                       u8 type = state->stack[spi].slot_type[(slot - i) %
+                                                             BPF_REG_SIZE];
 
                        if (type != STACK_MISC && type != STACK_ZERO) {
                                sanitize = true;