bpf: Disable zero-extension for BPF_MEMSX
authorIlya Leoshkevich <iii@linux.ibm.com>
Tue, 19 Sep 2023 10:09:03 +0000 (12:09 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 21 Sep 2023 21:21:59 +0000 (14:21 -0700)
On the architectures that use bpf_jit_needs_zext(), e.g., s390x, the
verifier incorrectly inserts a zero-extension after BPF_MEMSX, leading
to miscompilations like the one below:

      24:       89 1a ff fe 00 00 00 00 "r1 = *(s16 *)(r10 - 2);"       # zext_dst set
   0x3ff7fdb910e:       lgh     %r2,-2(%r13,%r0)                        # load halfword
   0x3ff7fdb9114:       llgfr   %r2,%r2                                 # wrong!
      25:       65 10 00 03 00 00 7f ff if r1 s> 32767 goto +3 <l0_1>   # check_cond_jmp_op()

Disable such zero-extensions. The JITs need to insert sign-extension
themselves, if necessary.

Suggested-by: Puranjay Mohan <puranjay12@gmail.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Puranjay Mohan <puranjay12@gmail.com>
Link: https://lore.kernel.org/r/20230919101336.2223655-2-iii@linux.ibm.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index 38f8718f160237c2c5bfa70de1226b2445135067..eed7350e15f49dfc3cb914bf4312f17a65503998 100644 (file)
@@ -3114,7 +3114,7 @@ static bool is_reg64(struct bpf_verifier_env *env, struct bpf_insn *insn,
 
        if (class == BPF_LDX) {
                if (t != SRC_OP)
-                       return BPF_SIZE(code) == BPF_DW;
+                       return BPF_SIZE(code) == BPF_DW || BPF_MODE(code) == BPF_MEMSX;
                /* LDX source must be ptr. */
                return true;
        }