[llvm] [llvm] Fix behavior of llvm.objectsize in presence of negative / large offset (PR #115504)

Nathan Chancellor via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 19 19:13:52 PST 2024


nathanchance wrote:

Hi @serge-sans-paille, I bisected a boot failure that I am seeing when building the Linux kernel with `CONFIG_UBSAN_BOUNDS`, `CONFIG_UBSAN_TRAP`, and `CONFIG_FORTIFY_SOURCE` to this change:

```
# bad: [c526eb891bda371c0481fcdc1507adc496431d03] Fix buildbots with no x86 target.
# good: [315519917368dce841f1cb1e7b296846d13497c3] Thread safety analysis: Eliminate unneeded const_cast, NFC
git bisect start 'c526eb891bda371c0481fcdc1507adc496431d03' '315519917368dce841f1cb1e7b296846d13497c3'
# bad: [6bf8f08989420ccd10efed5fac88052ca16e1250] [memprof] Add InstrProfWriter::addMemProfData (#116528)
git bisect bad 6bf8f08989420ccd10efed5fac88052ca16e1250
# bad: [0c04d43e8060f7b5bd4745c3400431abb3ad10b6] [RISCV][NFC] refactor CFI emitting (#114227)
git bisect bad 0c04d43e8060f7b5bd4745c3400431abb3ad10b6
# good: [1c4f335ec29c6bb269d0f8b2d6149d439312c69a] [PAC][lld] Use braa instr in PAC PLT sequence with valid PAuth core info (#113945)
git bisect good 1c4f335ec29c6bb269d0f8b2d6149d439312c69a
# bad: [63b926af5ff43a90dac285bbe0750e41e622eb3f] [mlir] Add apply_patterns.linalg.generalize_pack_unpack TD Op (#116373)
git bisect bad 63b926af5ff43a90dac285bbe0750e41e622eb3f
# good: [5ff52436fd0c7739765f1d849992713a3e9ae237] Relax clang/test/CodeGen/tbaa-pointers.c for -Asserts.
git bisect good 5ff52436fd0c7739765f1d849992713a3e9ae237
# good: [3c31ee740669fc80ff1bb4ae3724aa778cd1659e] [APInt] Call countTrailingZerosSlowCase() directly from isShiftedMask. NFC
git bisect good 3c31ee740669fc80ff1bb4ae3724aa778cd1659e
# bad: [1dcb3db0ac1255bf556bf6b62d03a113bd5191d8] [llvm] Fix behavior of llvm.objectsize in presence of negative / large offset (#115504)
git bisect bad 1dcb3db0ac1255bf556bf6b62d03a113bd5191d8
# good: [b4c0ef18226b7d1f82d71fc0171b99caec0d8d12] [flang][OpenMP] Add MLIR lowering for `loop ... bind` (#114219)
git bisect good b4c0ef18226b7d1f82d71fc0171b99caec0d8d12
# first bad commit: [1dcb3db0ac1255bf556bf6b62d03a113bd5191d8] [llvm] Fix behavior of llvm.objectsize in presence of negative / large offset (#115504)
```

The initial error I saw originated from `mm/slub.c` but after disabling UBSAN for that translation unit, another error popped up from `lib/crypto/sha256.c`. Looking at `lib/crypto/sha256.o`, it seems like this change causes `sha256_transform_blocks()` to get optimized to a simple `ud2`, so any call to it will just panic.

```
$ llvm-readelf -p .comment sha256.o
String dump of section '.comment':
[     1] ClangBuiltLinux clang version 20.0.0git (https://github.com/llvm/llvm-project.git 1dcb3db0ac1255bf556bf6b62d03a113bd5191d8)

$ llvm-objdump --disassemble-symbols=sha256_transform_blocks -r sha256.o

sha256.o: file format elf64-x86-64

Disassembly of section .text:

0000000000000100 <sha256_transform_blocks>:
     100: 0f 0b                         ud2
     102: 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00     nopw    %cs:(%rax,%rax)
```

At the immediately previous change, [this does not happen](https://github.com/nathanchance/bug-files/blob/2d2da3cdc10cd5413aa880a927f082a18936c1a1/llvm-1dcb3db0ac1255bf556bf6b62d03a113bd5191d8/good.txt).

`cvise` spits out:

```c
typedef unsigned long size_t;
struct sha256_state {
  long count;
  unsigned char buf[];
} lib_sha256_base_do_finalize_sctx;
typedef void(sha256_block_fn)(struct sha256_state *, unsigned char const *,
                              int);
int BLEND_OP___trans_tmp_2, sha256_transform_blocks_i;
int sha256_transform_blocks_W[64];
void *memset();
void memzero_explicit(void *s, size_t count) {
  memset(s, 0, count);
  __asm__ __volatile__("" : : "r"(s) : "memory");
}
int lib_sha256_base_do_update(sha256_block_fn block_fn) { return 0; }
int lib_sha256_base_do_finalize(sha256_block_fn block_fn) {
  long *bits = 0;
  block_fn(&lib_sha256_base_do_finalize_sctx,
           lib_sha256_base_do_finalize_sctx.buf, 1);
  *bits = 0;
  block_fn(&lib_sha256_base_do_finalize_sctx,
           lib_sha256_base_do_finalize_sctx.buf, 1);
  return 0;
}
static void sha256_transform_blocks(struct sha256_state *sctx,
                                    const unsigned char *input, int blocks) {
  int *__trans_tmp_3 = sha256_transform_blocks_W, *W = __trans_tmp_3;
  for (sha256_transform_blocks_i = 6; sha256_transform_blocks_i < 64;
       sha256_transform_blocks_i += 8) {
    {
      int *__trans_tmp_4 = W, *__trans_tmp_5 = W, *__trans_tmp_6 = W;
      {
        int I = sha256_transform_blocks_i;
        ;
        W[I] = __trans_tmp_4[7] + BLEND_OP___trans_tmp_2 + __trans_tmp_4[I - 6];
      }
      {
        int I = sha256_transform_blocks_i, word = __trans_tmp_5[5];
        BLEND_OP___trans_tmp_2 = word << 7;
        W[I] = __trans_tmp_5[7] + BLEND_OP___trans_tmp_2 + __trans_tmp_5[6];
      }
      {
        int I = sha256_transform_blocks_i, word = __trans_tmp_6[5];
        BLEND_OP___trans_tmp_2 = word;
        W[I] = __trans_tmp_6[7] + BLEND_OP___trans_tmp_2 + __trans_tmp_6[6];
      }
    }
  }
  memzero_explicit(sha256_transform_blocks_W,
                   sizeof(sha256_transform_blocks_W));
}
void sha256_update() { lib_sha256_base_do_update(sha256_transform_blocks); }
void sha224_final() { lib_sha256_base_do_finalize(sha256_transform_blocks); }
```

but I am not sure this is equivalent to the original code, so I have also uploaded [the full preprocessed file](https://github.com/nathanchance/bug-files/blob/2d2da3cdc10cd5413aa880a927f082a18936c1a1/llvm-1dcb3db0ac1255bf556bf6b62d03a113bd5191d8/sha256.i).

The behavior above can be reproduced with the following `clang` command with either file.

```
$ clang --target=x86_64-linux-gnu -fno-strict-overflow -fsanitize=local-bounds -mno-sse -O2 -c sha256.i
```

https://github.com/llvm/llvm-project/pull/115504


More information about the llvm-commits mailing list