[cfe-dev] Detecting undefined pointer arithmetic
Richard Smith via cfe-dev
cfe-dev at lists.llvm.org
Thu Jan 14 16:07:24 PST 2021
We do actually have (at least) two sanitizers that catch some cases of this
source of undefined behavior.
1) We have a pointer overflow sanitizer that catches pointer arithmetic
that wraps around the address space.
buf + very_large_number
2) We have an array bounds sanitizer that catches pointer arithmetic that
leaves the bounds of an array of known size.
int n = 7;
int arr[5];
int *p = arr + n;
Both checks are somewhat simplistic and could be extended to catch more
cases:
(1) could be taught to catch pointer arithmetic that leaves the bounds
determined by __builtin_object_size.
(2) could be taught to determine the known array bound in more cases, for
example catching '&n + 2' because (at least in C++) the language rules say
that 'n' is treated as an array of bound 1 for the purposes of pointer
arithmetic.
On Thu, 14 Jan 2021 at 08:03, John Criswell via cfe-dev <
cfe-dev at lists.llvm.org> wrote:
> Dear All,
>
> Actually, I think this is technically undefined behavior as (IIRC) C
> allows a pointer to extend one byte past the end of the referent memory
> object but not any further than that.
>
> That said, I wouldn’t be surprised if the sanitizers do not catch this
> case because:
>
>
> 1. Since the code doesn’t do anything useful, dead code elimination
> may remove the offending code before the sanitizers instrument the program.
> 2. The out of bounds pointer is not used to read or write memory, so
> it can’t corrupt or leak memory. About the most danger it poses is that it
> may enable optimizations that the programmer is not expecting because the
> code is undefined.
>
>
> I’ve lost track of all the different sanitizers in LLVM and how they work,
> but the original Address Sanitizer just checks for out of bounds loads and
> stores; it doesn’t place any checks on pointer arithmetic operations (like
> the LLVM gep instruction). That makes it faster at the cost of not
> catching all pointer arithmetic errors.
>
> Regards,
>
> John Criswell
>
> --
> John Criswell
> Associate Professor
> University of Rochester
> jtcriswel at gmail.com
>
>
>
>
>
> On Jan 14, 2021, at 9:39 AM, Marshall Clow via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
> On Jan 10, 2021, at 11:39 PM, Demi M. Obenour via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
> I noticed that none of the sanitizers seems to support checking for
> out-of-bounds pointer arithmetic, even though my understanding of
> the C standard is that this is undefined behavior. In particular, I
> believe the following trivial program has undefined behavior (assuming
> malloc() succeeds), but none of the sanitizers flag any warnings:
>
> #include <stdlib.h>
> int main(void) {
> char *buf = malloc(1);
> if (buf) {
> char *this_is_ub = buf + 3;
> free(buf);
> }
> }
>
> Of course, I suspect this just has not been implemented yet, but
> it still leaves me at a loss for how to track this form of UB down.
> Is there a better solution than manual code review?
>
>
>
> This program does not have UB.
> There’s nothing wrong with forming an "out-of-bound” pointer.
> If you use it for anything, then that is UB - and address sanitizer will
> find such usages for you.
>
> Like this:
>
> #include <stdlib.h>
> int main(void) {
> int ret = 0;
> char *buf = (char *) malloc(1);
> if (buf) {
> char *this_is_ub = buf + 3;
> ret = *this_is_ub;
> free(buf);
> }
> return ret;
> }
>
> ——
> % clang++ -fsanitize=address bug.cpp && ./a.out
> =================================================================
> ==25602==ERROR: AddressSanitizer: heap-buffer-overflow on address
> 0x6020000000d3 at pc 0x00010531ff18 bp 0x7ffeea8e0970 sp 0x7ffeea8e0968
> READ of size 1 at 0x6020000000d3 thread T0
> #0 0x10531ff17 in main (a.out:x86_64+0x100000f17)
> #1 0x7fff6edd5cc8 in start (libdyld.dylib:x86_64+0x1acc8)
>
> 0x6020000000d3 is located 2 bytes to the right of 1-byte region
> [0x6020000000d0,0x6020000000d1)
> allocated by thread T0 here:
> #0 0x105e08abd in wrap_malloc
> (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x45abd)
> #1 0x10531feaf in main (a.out:x86_64+0x100000eaf)
> #2 0x7fff6edd5cc8 in start (libdyld.dylib:x86_64+0x1acc8)
>
> SUMMARY: AddressSanitizer: heap-buffer-overflow (a.out:x86_64+0x100000f17)
> in main
> Shadow bytes around the buggy address:
> 0x1c03ffffffc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x1c03ffffffd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x1c03ffffffe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x1c03fffffff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x1c0400000000: fa fa fd fd fa fa 00 00 fa fa 00 00 fa fa 00 04
> =>0x1c0400000010: fa fa 00 00 fa fa 00 06 fa fa[01]fa fa fa fa fa
> 0x1c0400000020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> 0x1c0400000030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> 0x1c0400000040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> 0x1c0400000050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> 0x1c0400000060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> 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
> ==25602==ABORTING
> zsh: abort ./a.out
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20210114/6ce58247/attachment-0001.html>
More information about the cfe-dev
mailing list