Skip to content

Address sanitizer false positive when calling FFI function #87215

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
crumblingstatue opened this issue Jul 17, 2021 · 1 comment
Closed

Address sanitizer false positive when calling FFI function #87215

crumblingstatue opened this issue Jul 17, 2021 · 1 comment
Labels
C-bug Category: This is a bug.

Comments

@crumblingstatue
Copy link
Contributor

crumblingstatue commented Jul 17, 2021

When calling an extern C function with a specific signature, -Zsanitize=address reports a false positive error.
I included a C version of calling the same function in the same way, which reports no error.

Seems to only trigger with opt-level=0. If the Rust version is built with opt-level=1 or above, no error gets reported.

mytestlib.h:

typedef struct
{
    int a;
    int b;
    int c;
} Foo;

void bar(Foo foo, const char* bytes);

mytestlib.c:

// clang -shared mytestlib.c -o libmytestlib.so

#include "mytestlib.h"

void bar(Foo foo, const char* bytes)
{
}

cver.c:

// clang -I. cver.c -L. -fsanitize=address -lmytestlib -o cver

#include "mytestlib.h"

int main() {
    Foo foo = {0, 0, 0};
    const char bytes[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    bar(foo, bytes);
}

rustver.rs:

// rustc rustver.rs -L. -lmytestlib -Z sanitizer=address

#![allow(non_snake_case)]

use std::os::raw::{c_char, c_int, c_void};

#[repr(C)]
struct Foo {
    a: c_int,
    b: c_int,
    c: c_int,
}

extern "C" {
    fn bar(
        foo: Foo,
        bytes: *const c_char
    ) -> c_void;
}

fn main() {
    let mode = Foo {
        a: 0,
        b: 0,
        c: 0,
    };
    let bytes = [0i8; 16];
    unsafe {
        bar(mode, bytes.as_ptr());
    }
}

Sanitizer output of Rust version:

==49283==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffcae60082f at pc 0x5602f4817870 bp 0x7ffcae6007f0 sp 0x7ffcae6007e8
READ of size 16 at 0x7ffcae60082f thread T0
    #0 0x5602f481786f in rustver::main::h9c19e03384d64f73 (/tmp/sftest/rustver+0x9a86f)
    #1 0x5602f48180c2 in core::ops::function::FnOnce::call_once::hd1707a0f7551fbaf (/tmp/sftest/rustver+0x9b0c2)
    #2 0x5602f48179dd in std::sys_common::backtrace::__rust_begin_short_backtrace::h4bf5b3587a924875 (/tmp/sftest/rustver+0x9a9dd)
    #3 0x5602f4817d1e in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h7082ba1ef153c8f6 (/tmp/sftest/rustver+0x9ad1e)
    #4 0x5602f48285a9 in core::ops::function::impls::_$LT$impl$u20$core..ops..function..FnOnce$LT$A$GT$$u20$for$u20$$RF$F$GT$::call_once::h61bcc1dec5918b7e /rustc/74ef0c3e404cc72c08b2d1e14506f90d9e877269/library/core/src/ops/function.rs:259:13
    #5 0x5602f48285a9 in std::panicking::try::do_call::h672d24f85ce22db4 /rustc/74ef0c3e404cc72c08b2d1e14506f90d9e877269/library/std/src/panicking.rs:401:40
    #6 0x5602f48285a9 in std::panicking::try::he383e7ef11604e58 /rustc/74ef0c3e404cc72c08b2d1e14506f90d9e877269/library/std/src/panicking.rs:365:19
    #7 0x5602f48285a9 in std::panic::catch_unwind::h502ac6058961e393 /rustc/74ef0c3e404cc72c08b2d1e14506f90d9e877269/library/std/src/panic.rs:434:14
    #8 0x5602f48285a9 in std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::h851ee37bb5d99fdf /rustc/74ef0c3e404cc72c08b2d1e14506f90d9e877269/library/std/src/rt.rs:45:48
    #9 0x5602f48285a9 in std::panicking::try::do_call::h84f41bb3453bbd14 /rustc/74ef0c3e404cc72c08b2d1e14506f90d9e877269/library/std/src/panicking.rs:401:40
    #10 0x5602f48285a9 in std::panicking::try::h969c45dbbf2e4c94 /rustc/74ef0c3e404cc72c08b2d1e14506f90d9e877269/library/std/src/panicking.rs:365:19
    #11 0x5602f48285a9 in std::panic::catch_unwind::he40b1a4614f73e03 /rustc/74ef0c3e404cc72c08b2d1e14506f90d9e877269/library/std/src/panic.rs:434:14
    #12 0x5602f48285a9 in std::rt::lang_start_internal::h0fbab25cccdb30d8 /rustc/74ef0c3e404cc72c08b2d1e14506f90d9e877269/library/std/src/rt.rs:45:20
    #13 0x5602f4817c80 in std::rt::lang_start::h545ca672193475cc (/tmp/sftest/rustver+0x9ac80)
    #14 0x5602f4817912 in main (/tmp/sftest/rustver+0x9a912)
    #15 0x7f712db19b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
    #16 0x5602f478a6bd in _start (/tmp/sftest/rustver+0xd6bd)

Address 0x7ffcae60082f is located in stack of thread T0 at offset 47 in frame
    #0 0x5602f48175ff in rustver::main::h9c19e03384d64f73 (/tmp/sftest/rustver+0x9a5ff)

  This frame has 3 object(s):
    [32, 44) '_4'
    [64, 80) 'bytes' <== Memory access at offset 47 underflows this variable
    [96, 108) 'mode'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/tmp/sftest/rustver+0x9a86f) in rustver::main::h9c19e03384d64f73
Shadow bytes around the buggy address:
  0x100015cb80b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100015cb80c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100015cb80d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100015cb80e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100015cb80f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100015cb8100: f1 f1 f1 f1 00[04]f2 f2 00 00 f2 f2 00 04 f3 f3
  0x100015cb8110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100015cb8120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100015cb8130: f1 f1 f1 f1 f8 f8 f3 f3 00 00 00 00 00 00 00 00
  0x100015cb8140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100015cb8150: 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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  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
  Shadow gap:              cc

Meta:
rustc 1.55.0-nightly (74ef0c3 2021-07-16)
Linux 5.13.1-arch1-1 #1 SMP PREEMPT Fri, 09 Jul 2021 23:42:24 +0000 x86_64 GNU/Linux

@crumblingstatue crumblingstatue added the C-bug Category: This is a bug. label Jul 17, 2021
@tmiasko
Copy link
Contributor

tmiasko commented Jul 17, 2021

Thanks for reporting. opt-level >= 1 usually workarounds the issue as you observed.

Duplicate of #75839

@tmiasko tmiasko closed this as completed Feb 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

2 participants