libmagic: fix ASR padding for memory mapping

The code could not decide whether to apply the padding to the start
or the end of the region, resulting in strange behavior because part
of the returned range might not have the right properties.  With this
patch, padding is now consistently applied at the end of the region,
since virtual mmap addresses are allocated from high to low.

Also fix a few small related bugs in error handling code.

Change-Id: I327814bb3921d7982ffc1296a5bf365d9c79c1d9
This commit is contained in:
David van Moolenbroek 2015-09-04 03:28:24 +02:00
parent 65c4b82f02
commit f55e3cae08
2 changed files with 6 additions and 6 deletions

View file

@ -695,7 +695,7 @@ PRIVATE int magic_free_dsentry(struct _magic_dsentry *dsentry)
if (!MAGIC_STATE_FLAG(sentry, MAGIC_STATE_DETACHED)) { if (!MAGIC_STATE_FLAG(sentry, MAGIC_STATE_DETACHED)) {
size_t padding_size = (size_t) dsentry->ext; size_t padding_size = (size_t) dsentry->ext;
MAGIC_MEM_DEBUG_FREE(ptr); MAGIC_MEM_DEBUG_FREE(ptr);
ret = munmap(((char *)aligned_ptr) - padding_size, page_size + size + padding_size); ret = munmap((char *)aligned_ptr, page_size + size + padding_size);
} }
else { else {
#ifndef __MINIX #ifndef __MINIX
@ -1708,7 +1708,7 @@ PUBLIC void *magic_mmap_positioned(__MA_ARGS__ void *start, size_t length, int p
new_start = ((char *)ptr) + page_size; new_start = ((char *)ptr) + page_size;
new_ptr = mmap(new_start, length, prot, flags | MAP_FIXED, fd, offset); new_ptr = mmap(new_start, length, prot, flags | MAP_FIXED, fd, offset);
if (new_ptr == MAP_FAILED) { if (new_ptr == MAP_FAILED) {
munmap(ptr, page_size + alloc_length); munmap(ptr, page_size + alloc_length + padding_size);
ptr = MAP_FAILED; ptr = MAP_FAILED;
} }
} }
@ -1716,7 +1716,7 @@ PUBLIC void *magic_mmap_positioned(__MA_ARGS__ void *start, size_t length, int p
aligned_ptr = ptr; aligned_ptr = ptr;
MAGIC_MEM_PRINTF("magic_mmap: ptr = mmap(start, length, prot, flags, fd, offset) <-> 0x%08x = mmap(0x%08x, %d, 0x%08x, 0x%08x, %d, %d)\n", (unsigned) aligned_ptr, aligned_start, page_size + length, prot, flags, fd, offset); MAGIC_MEM_PRINTF("magic_mmap: ptr = mmap(start, length, prot, flags, fd, offset) <-> 0x%08x = mmap(0x%08x, %d, 0x%08x, 0x%08x, %d, %d)\n", (unsigned) aligned_ptr, aligned_start, page_size + length, prot, flags, fd, offset);
if (ptr != MAP_FAILED) { if (ptr != MAP_FAILED) {
ptr = ((char *)ptr) + padding_size + page_size - MAGIC_SIZE_TO_REAL(0); ptr = ((char *)ptr) + page_size - MAGIC_SIZE_TO_REAL(0);
} }
else { else {
ptr = NULL; ptr = NULL;
@ -1725,14 +1725,14 @@ PUBLIC void *magic_mmap_positioned(__MA_ARGS__ void *start, size_t length, int p
dsentry_flags |= MAGIC_STATE_SHM; dsentry_flags |= MAGIC_STATE_SHM;
data_ptr = magic_alloc(__MA_VALUES__ ptr, alloc_length, dsentry_flags); data_ptr = magic_alloc(__MA_VALUES__ ptr, alloc_length, dsentry_flags);
if (data_ptr == MAGIC_MEM_FAILED) { if (data_ptr == MAGIC_MEM_FAILED) {
munmap(aligned_ptr, page_size + length); munmap(aligned_ptr, page_size + alloc_length + padding_size);
data_ptr = NULL; data_ptr = NULL;
errno = ENOMEM;
} }
if (!data_ptr) { if (!data_ptr) {
errno = ENOMEM; errno = ENOMEM;
data_ptr = MAP_FAILED; data_ptr = MAP_FAILED;
} else { } else {
assert(data_ptr == (char *)aligned_ptr + page_size);
MAGIC_PTR_TO_DSENTRY(MAGIC_PTR_FROM_DATA(data_ptr))->alloc_mmap_flags = flags; MAGIC_PTR_TO_DSENTRY(MAGIC_PTR_FROM_DATA(data_ptr))->alloc_mmap_flags = flags;
MAGIC_PTR_TO_DSENTRY(MAGIC_PTR_FROM_DATA(data_ptr))->alloc_mmap_prot = prot; MAGIC_PTR_TO_DSENTRY(MAGIC_PTR_FROM_DATA(data_ptr))->alloc_mmap_prot = prot;
MAGIC_PTR_TO_DSENTRY(MAGIC_PTR_FROM_DATA(data_ptr))->ext = (void *) padding_size; MAGIC_PTR_TO_DSENTRY(MAGIC_PTR_FROM_DATA(data_ptr))->ext = (void *) padding_size;

View file

@ -3374,7 +3374,7 @@ PRIVATE int allocate_pair_metadata_dsentries(st_init_info_t *info,
* in order to free the preceding page, containing the dsentry struct, too. * in order to free the preceding page, containing the dsentry struct, too.
*/ */
MAGIC_MEM_WRAPPER_BLOCK( MAGIC_MEM_WRAPPER_BLOCK(
res = munmap((char *)sentry->address - magic_get_sys_pagesize() - padding, size + magic_get_sys_pagesize() + padding); res = munmap((char *)sentry->address - magic_get_sys_pagesize(), size + magic_get_sys_pagesize() + padding);
); );
if (res != 0) { if (res != 0) {
printf("ERROR, munmap returned NULL.\n"); printf("ERROR, munmap returned NULL.\n");