forked from OSchip/llvm-project
				
			[asan] Check for pvalloc overlow
Summary: Last one of the `pvalloc` overflow checks! `CheckForPvallocOverflow` was introduced with D35818 to detect when `pvalloc` would wrap when rounding up to the next multiple of the page size. Add this check to ASan's `pvalloc` implementation. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D36257 llvm-svn: 310119
This commit is contained in:
		
							parent
							
								
									b24df62bb6
								
							
						
					
					
						commit
						d7d1681a0e
					
				| 
						 | 
					@ -839,6 +839,10 @@ void *asan_valloc(uptr size, BufferedStackTrace *stack) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *asan_pvalloc(uptr size, BufferedStackTrace *stack) {
 | 
					void *asan_pvalloc(uptr size, BufferedStackTrace *stack) {
 | 
				
			||||||
  uptr PageSize = GetPageSizeCached();
 | 
					  uptr PageSize = GetPageSizeCached();
 | 
				
			||||||
 | 
					  if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) {
 | 
				
			||||||
 | 
					    errno = errno_ENOMEM;
 | 
				
			||||||
 | 
					    return AsanAllocator::FailureHandler::OnBadRequest();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  // pvalloc(0) should allocate one page.
 | 
					  // pvalloc(0) should allocate one page.
 | 
				
			||||||
  size = size ? RoundUpTo(size, PageSize) : PageSize;
 | 
					  size = size ? RoundUpTo(size, PageSize) : PageSize;
 | 
				
			||||||
  return SetErrnoOnNull(
 | 
					  return SetErrnoOnNull(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					// RUN: %clangxx_asan  %s -o %t
 | 
				
			||||||
 | 
					// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %run %t m1 2>&1 | FileCheck %s
 | 
				
			||||||
 | 
					// RUN: ASAN_OPTIONS=allocator_may_return_null=1     %run %t m1 2>&1
 | 
				
			||||||
 | 
					// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %run %t psm1 2>&1 | FileCheck %s
 | 
				
			||||||
 | 
					// RUN: ASAN_OPTIONS=allocator_may_return_null=1     %run %t psm1 2>&1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UNSUPPORTED: freebsd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Checks that pvalloc overflows are caught. If the allocator is allowed to
 | 
				
			||||||
 | 
					// return null, the errno should be set to ENOMEM.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <malloc.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char *argv[]) {
 | 
				
			||||||
 | 
					  void *p;
 | 
				
			||||||
 | 
					  size_t page_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert(argc == 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  page_size = sysconf(_SC_PAGESIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!strcmp(argv[1], "m1")) {
 | 
				
			||||||
 | 
					    p = pvalloc((uintptr_t)-1);
 | 
				
			||||||
 | 
					    assert(!p);
 | 
				
			||||||
 | 
					    assert(errno == ENOMEM);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!strcmp(argv[1], "psm1")) {
 | 
				
			||||||
 | 
					    p = pvalloc((uintptr_t)-(page_size - 1));
 | 
				
			||||||
 | 
					    assert(!p);
 | 
				
			||||||
 | 
					    assert(errno == ENOMEM);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CHECK: AddressSanitizer's allocator is terminating the process
 | 
				
			||||||
		Loading…
	
		Reference in New Issue