diff options
Diffstat (limited to 'support/xsigstack.c')
-rw-r--r-- | support/xsigstack.c | 43 |
1 files changed, 5 insertions, 38 deletions
diff --git a/support/xsigstack.c b/support/xsigstack.c index a2f0e32..a471c85 100644 --- a/support/xsigstack.c +++ b/support/xsigstack.c @@ -37,8 +37,7 @@ structures. */ struct sigstack_desc { - void *alloc_base; /* Base address of the complete allocation. */ - size_t alloc_size; /* Size of the complete allocation. */ + struct support_stack stack; stack_t alt_stack; /* The address and size of the stack itself. */ stack_t old_stack; /* The previous signal stack. */ }; @@ -46,43 +45,11 @@ struct sigstack_desc void * xalloc_sigstack (size_t size) { - size_t pagesize = sysconf (_SC_PAGESIZE); - if (pagesize == -1) - FAIL_EXIT1 ("sysconf (_SC_PAGESIZE): %m\n"); - - /* Always supply at least MINSIGSTKSZ space; passing 0 as size means - only that much space. No matter what the number is, round it up - to a whole number of pages. */ - size_t stacksize = roundup (size + MINSIGSTKSZ, pagesize); - - /* The guard bands need to be large enough to intercept offset - accesses from a stack address that might otherwise hit another - mapping. Make them at least twice as big as the stack itself, to - defend against an offset by the entire size of a large - stack-allocated array. The minimum is 1MiB, which is arbitrarily - chosen to be larger than any "typical" wild pointer offset. - Again, no matter what the number is, round it up to a whole - number of pages. */ - size_t guardsize = roundup (MAX (2 * stacksize, 1024 * 1024), pagesize); - struct sigstack_desc *desc = xmalloc (sizeof (struct sigstack_desc)); - desc->alloc_size = guardsize + stacksize + guardsize; - /* Use MAP_NORESERVE so that RAM will not be wasted on the guard - bands; touch all the pages of the actual stack before returning, - so we know they are allocated. */ - desc->alloc_base = xmmap (0, - desc->alloc_size, - PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE|MAP_STACK, - -1); - - xmprotect (desc->alloc_base, guardsize, PROT_NONE); - xmprotect (desc->alloc_base + guardsize + stacksize, guardsize, PROT_NONE); - memset (desc->alloc_base + guardsize, 0xA5, stacksize); - - desc->alt_stack.ss_sp = desc->alloc_base + guardsize; + desc->stack = support_stack_alloc (size); + desc->alt_stack.ss_sp = desc->stack.stack; desc->alt_stack.ss_flags = 0; - desc->alt_stack.ss_size = stacksize; + desc->alt_stack.ss_size = desc->stack.size; if (sigaltstack (&desc->alt_stack, &desc->old_stack)) FAIL_EXIT1 ("sigaltstack (new stack: sp=%p, size=%zu, flags=%u): %m\n", @@ -101,7 +68,7 @@ xfree_sigstack (void *stack) FAIL_EXIT1 ("sigaltstack (restore old stack: sp=%p, size=%zu, flags=%u): " "%m\n", desc->old_stack.ss_sp, desc->old_stack.ss_size, desc->old_stack.ss_flags); - xmunmap (desc->alloc_base, desc->alloc_size); + support_stack_free (&desc->stack); free (desc); } |