diff options
author | vanhauser-thc <vh@thc.org> | 2021-03-16 16:15:29 +0100 |
---|---|---|
committer | vanhauser-thc <vh@thc.org> | 2021-03-16 16:15:29 +0100 |
commit | f5420e737a1ed1dbeb81783836d0449c06aa0fcc (patch) | |
tree | 0b6f5863b286c9727558a3973b70d7ff0297a04d /instrumentation/afl-compiler-rt.o.c | |
parent | 4e567d3f5d22ae14bffc17cc8d475959d5fcfc21 (diff) | |
download | afl++-f5420e737a1ed1dbeb81783836d0449c06aa0fcc.tar.gz |
rtn fix
Diffstat (limited to 'instrumentation/afl-compiler-rt.o.c')
-rw-r--r-- | instrumentation/afl-compiler-rt.o.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 50b4e2c5..892118fb 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1734,25 +1734,26 @@ static int area_is_valid(void *ptr, size_t len) { long r = syscall(SYS_write, __afl_dummy_fd[1], ptr, len); - if (unlikely(r <= 0 || r > len)) { // fail - maybe hitting asan boundary? + if (r <= 0 || r > len) return 0; - char *p = (char *)ptr; - long page_size = sysconf(_SC_PAGE_SIZE); - char *page = (char *)((uintptr_t)p & ~(page_size - 1)) + page_size; - if (page >= p + len) { return 0; } // no isnt, return fail - len = page - p - len; - r = syscall(SYS_write, __afl_dummy_fd[1], page, len); + // even if the write succeed this can be a false positive if we cross + // a page boundary. who knows why. - } + char *p = (char *)ptr; + long page_size = sysconf(_SC_PAGE_SIZE); + char *page = (char *)((uintptr_t)p & ~(page_size - 1)) + page_size; - // partial writes - we return what was written. - if (likely(r >= 0 && r <= len)) { + if (page > p + len) { + // no, not crossing a page boundary return (int)r; } else { - return 0; + // yes it crosses a boundary, hence we can only return the length of + // rest of the first page, we cannot detect if the next page is valid + // or not, neither by SYS_write nor msync() :-( + return (int)(page - p); } |