Closed
Description
Update
STR
fn main () {
let mut x = (4, ());
unsafe {
std::ptr::write(&mut x, (3, ()));
}
}
$ RUSTFLAGS="-Z sanitizer=address" cargo run --target x86_64-unknown-linux-gnu
Running `target/x86_64-unknown-linux-gnu/debug/gh39882`
=================================================================
==25622==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffcdeb06284 at pc 0x55e19fbf269b bp 0x7ffcdeb06250 sp 0x7ffcdeb06248
ACCESS of size 0 at 0x7ffcdeb06284 thread T0
(..)
This frame has 3 object(s):
[32, 36) 'arg' <== Memory access at offset 36 is inside this variable
[48, 52) '_7'
[64, 68) 'x'
(..)
Meta
$ rustc -V
rustc 1.17.0-nightly (60a0edc6c 2017-02-26)
Cause
We produce loads of the zero sized types in LLVM-IR.
$ cargo rustc -- --emit=llvm-ir
$ cat $(find -name '*.ll')
define internal void @_ZN7gh398824main17hc6881d8c6f884174E() unnamed_addr #1 !dbg !34 {
entry-block:
(..)
start:
(..)
%6 = getelementptr inbounds { i32, {} }, { i32, {} }* %arg, i32 0, i32 1, !dbg !42
store {} undef, {}* %6, !dbg !42
(..)
Workaround
Append a non zero sized type to your struct so the ZST is not the last field of the struct. You could do this only if a feature is enabled to avoid changing the API of your crate.
pub struct Offender {
payload: u32,
zero_sized_type: (), // or PhantomData
#[cfg(feature = "asan")]
workaround: u8,
}
Then test with:
$ RUSTFLAGS="-Z sanitizer=address" cargo run --target x86_64-unknown-linux-gnu --feature asan
Fix
Remove those loads by specializing the treatment of zero sized types in trans. As per @eddyb comment.
Original report
program:
use std::collections::HashSet;
pub fn main() {
let mut hash_set = HashSet::<i32>::new();
hash_set.insert(42);
}
rustc version: 1.17.0-nightly (62eb605 2017-02-15)
build:
[asan]$ RUSTFLAGS="-Z sanitizer=address" cargo +nightly build --target x86_64-unknown-linux-gnu
Compiling asan v0.1.0 (file:///data/dch/asan)
Finished dev [unoptimized + debuginfo] target(s) in 1.8 secs
result:
[asan]$ ./target/x86_64-unknown-linux-gnu/debug/asan
=================================================================
==3100==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd196acb24 at pc 0x7f4a672abbd6 bp 0x7ffd196acaf0 sp 0x7ffd196acae8
ACCESS of size 0 at 0x7ffd196acb24 thread T0
#0 0x7f4a672abbd5 in _$LT$std..collections..hash..table..EmptyBucket$LT$K$C$$u20$V$C$$u20$M$GT$$GT$::put::h4dcbd19464a4eb32 /checkout/src/libstd/collections
/hash/table.rs:450
#1 0x7f4a672ac7e7 in _$LT$std..collections..hash..map..VacantEntry$LT$$u27$a$C$$u20$K$C$$u20$V$GT$$GT$::insert::h1f23562a9244108b /checkout/src/libstd/colle
ctions/hash/map.rs:2070
#2 0x7f4a672a3d34 in _$LT$std..collections..hash..map..HashMap$LT$K$C$$u20$V$C$$u20$S$GT$$GT$::insert_hashed_nocheck::hc786fd8d25a77f8d /checkout/src/libstd
/collections/hash/map.rs:805
#3 0x7f4a672a4c28 in _$LT$std..collections..hash..map..HashMap$LT$K$C$$u20$V$C$$u20$S$GT$$GT$::insert::h807e2aa556ba41aa /checkout/src/libstd/collections/ha
sh/map.rs:1150
#4 0x7f4a6729e793 in _$LT$std..collections..hash..set..HashSet$LT$T$C$$u20$S$GT$$GT$::insert::h4a1f9ecc174ad965 /checkout/src/libstd/collections/hash/set.rs
:585
#5 0x7f4a672ad401 in asan::main::h9b63a9a755bc73af /data/dch/asan/src/main.rs:5
#6 0x7f4a673a787a in __rust_maybe_catch_panic /checkout/src/libpanic_unwind/lib.rs:98
#7 0x7f4a673a00b6 in std::panicking::try<(),fn()> /checkout/src/libstd/panicking.rs:429
#8 0x7f4a673a00b6 in std::panic::catch_unwind<fn(),()> /checkout/src/libstd/panic.rs:361
#9 0x7f4a673a00b6 in std::rt::lang_start::hb7fc7ec87b663023 /checkout/src/libstd/rt.rs:57
#10 0x7f4a672ad4d2 in main (/data/dch/asan/target/x86_64-unknown-linux-gnu/debug/asan+0x284d2)
#11 0x7f4a66485b34 in __libc_start_main (/lib64/libc.so.6+0x21b34)
#12 0x7f4a6728e6a5 in _start (/data/dch/asan/target/x86_64-unknown-linux-gnu/debug/asan+0x96a5)
Address 0x7ffd196acb24 is located in stack of thread T0 at offset 36 in frame
#0 0x7f4a672ab68f in _$LT$std..collections..hash..table..EmptyBucket$LT$K$C$$u20$V$C$$u20$M$GT$$GT$::put::h4dcbd19464a4eb32 /checkout/src/libstd/collections
/hash/table.rs:447
This frame has 8 object(s):
[32, 36) 'arg' <== Memory access at offset 36 is inside this variable
[48, 64) '_20'
[80, 84) '_15'
[96, 104) 'hash'
[128, 160) 'self'
[192, 200) 'abi_cast'
[224, 232) 'arg1'
[256, 288) 'arg0'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /checkout/src/libstd/collections/hash/table.rs:450 in _$LT$std..collections..hash..table..EmptyBucket$LT$K$C$$u
20$V$C$$u20$M$GT$$GT$::put::h4dcbd19464a4eb32
Shadow bytes around the buggy address:
0x1000232cd910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000232cd920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000232cd930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000232cd940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000232cd950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1000232cd960: f1 f1 f1 f1[04]f2 00 00 f2 f2 04 f2 00 f2 f2 f2
0x1000232cd970: 00 00 00 00 f2 f2 f2 f2 00 f2 f2 f2 00 f2 f2 f2
0x1000232cd980: 00 00 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00
0x1000232cd990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000232cd9a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000232cd9b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==3100==ABORTING
Of course it's possible that this is a false positive, though my experience in C and C++ has been that it's very rare indeed for the address sanitiser to produce such.