google / sanitizers

AddressSanitizer, ThreadSanitizer, MemorySanitizer
Other
11.55k stars 1.04k forks source link

Potential false negative for underflow #1799

Open evintila opened 2 months ago

evintila commented 2 months ago

Dear ASan authors,

We have noticed that ASan, under certain conditions, does not detect off-by-one underflows, and are wondering if this is expected behavior. Note that off-by-one overflows are detected.

In the following example, the underflow is not detected. Note that this also happens when reading from the pointer.

char buff[8];
int main()
{
  char *aux_ptr = &buff[0] - 1;
  *aux_ptr = 'x'; // off-by-one underflow NOT detected

  return 0;
}

Defining an initialized pointer after buff leads to the detection of the memory bug:

char buff[8];
char *p = NULL;

int main()
{
  char *aux_ptr = &buff[0] - 1;
  *aux_ptr = 'x'; // off-by-one underflow detected

  return 0;
}

With the expected error message:

=================================================================
==26138==ERROR: AddressSanitizer: global-buffer-overflow on address 0x558b4847cdbf at pc 0x558b47ae48ef bp 0x7ffdc6ffefa0 sp 0x7ffdc6ffef98
WRITE of size 1 at 0x558b4847cdbf thread T0
<...>
==26138==ABORTING

Compiler versions used:

clang version 19.1.0-rc4 (https://github.com/llvm/llvm-project.git f0010d131b79a1b401777aa32e96defc4a935c9d)
Target: x86_64-unknown-linux-gnu

and

clang version 20.0.0git (https://github.com/llvm/llvm-project.git 5c406eacf4f4dda0cf9267d638954aa20f17e118)
Target: x86_64-unknown-linux-gnu

Flags used: -fsanitize=address

vitalybuka commented 2 months ago

This is because we insert read zones only after the global. Multiple global will protect each other.

https://godbolt.org/z/e3sd57MhE