|
Message-Id: <E5BAF7C1-74B1-4C71-9B01-53609D3E5971@gmail.com> Date: Mon, 9 Jan 2017 09:47:35 +0100 From: Julien Ramseier <j.ramseier@...il.com> To: musl@...ts.openwall.com Subject: [PATCH] malloc: always fail with ENOMEM malloc may set errno to something else than ENOMEM indirectly through mmap, though ENOMEM is the only error allowed by POSIX. There are cases where mmap will return EPERM instead of ENOMEM, as highlighted by libc-test[1]. This can happen when mmap tries to map pages near `mmap_min_addr` [2][3], as a security measure. [1] http://www.openwall.com/lists/musl/2016/03/30/9 [2] https://ghc.haskell.org/trac/ghc/ticket/7500 [3] https://github.com/torvalds/linux/blob/master/security/min_addr.c diff --git a/src/malloc/expand_heap.c b/src/malloc/expand_heap.c index d8c0be7..4051b1b 100644 --- a/src/malloc/expand_heap.c +++ b/src/malloc/expand_heap.c @@ -65,7 +65,10 @@ void *__expand_heap(size_t *pn) if (n < min) n = min; void *area = __mmap(0, n, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - if (area == MAP_FAILED) return 0; + if (area == MAP_FAILED) { + errno = ENOMEM; + return 0; + } *pn = n; mmap_step++; return area; diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index c38c46f..593c4dd 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -328,7 +328,10 @@ void *malloc(size_t n) size_t len = n + OVERHEAD + PAGE_SIZE - 1 & -PAGE_SIZE; char *base = __mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - if (base == (void *)-1) return 0; + if (base == MAP_FAILED) { + errno = ENOMEM; + return 0; + } c = (void *)(base + SIZE_ALIGN - OVERHEAD); c->csize = len - (SIZE_ALIGN - OVERHEAD); c->psize = SIZE_ALIGN - OVERHEAD;
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.