public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/63303] New: Pointer subtraction is broken when using -fsanitize=undefined
@ 2014-09-19  1:42 mikulas at artax dot karlin.mff.cuni.cz
  2014-09-19  7:26 ` [Bug c/63303] " jakub at gcc dot gnu.org
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: mikulas at artax dot karlin.mff.cuni.cz @ 2014-09-19  1:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63303

            Bug ID: 63303
           Summary: Pointer subtraction is broken when using
                    -fsanitize=undefined
           Product: gcc
           Version: 4.9.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mikulas at artax dot karlin.mff.cuni.cz
              Host: x86_64-linux-gnux32
            Target: x86_64-linux-gnux32
             Build: x86_64-linux-gnux32

The undefined behavior sanitizer incorrectly warns about pointer subtraction.

The reason is that the undefined behavior sanitizer treats pointer subtraction
like subtraction of two signed integers and warns if it would result in integer
overflow. However, this logic is incorrect.

Subtracting of these two pointers is perfectly legal operation but it results
in incorrect warning: (char *)0x90000000 - (char *)0x70000000: this bug causes
spurious warnings in correct program if array spans the boundary 0x80000000 and
the program subtracts pointers in this array.

Subtracting these two pointers doesn't result in a warning, but it should
because the resulting integer overflows: (char *)0xc0000000 - (char
*)0x30000000

BTW. The sanitizer also lacks warnings when addition of a pointer and integer
results in overflow. For example (char *)0xd0000000 + 0x40000000U doesn't
result in a warning but it should.

This is the example code, compile it with -fsanitize=undefined

#include <stdio.h>
#include <stddef.h>

__attribute((noinline,noclone)) ptrdiff_t ptr_diff(char *p1, char *p2)
{
        return p1 - p2;
}

__attribute((noinline,noclone)) void *ptr_add(char *p1, unsigned long p2)
{
        return p1 + p2;
}

void *get_address(unsigned n)
{
        return (void *)((unsigned long)n << (sizeof(void *) * 8 - 4));
}

int main(void)
{
        printf("%ld\n", (long)ptr_diff(get_address(0x9), get_address(0x7))); /*
sanitizer should not warn here */
        printf("%ld\n", (long)ptr_diff(get_address(0xc), get_address(0x3))); /*
sanitizer should warn here */
        return 0;
}


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-10-19 11:03 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-19  1:42 [Bug c/63303] New: Pointer subtraction is broken when using -fsanitize=undefined mikulas at artax dot karlin.mff.cuni.cz
2014-09-19  7:26 ` [Bug c/63303] " jakub at gcc dot gnu.org
2014-09-19 13:38 ` mikulas at artax dot karlin.mff.cuni.cz
2014-09-19 13:47 ` jakub at gcc dot gnu.org
2014-09-19 15:50 ` mikulas at artax dot karlin.mff.cuni.cz
2014-09-19 15:57 ` jakub at gcc dot gnu.org
2014-09-19 16:15 ` mikulas at artax dot karlin.mff.cuni.cz
2014-09-19 16:21 ` joseph at codesourcery dot com
2014-09-19 16:22 ` jakub at gcc dot gnu.org
2014-09-19 16:29 ` mikulas at artax dot karlin.mff.cuni.cz
2014-09-22  7:42 ` rguenth at gcc dot gnu.org
2014-09-22 14:31 ` mikulas at artax dot karlin.mff.cuni.cz
2015-10-19 11:03 ` rguenth at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).