Module Name: src Committed By: uebayasi Date: Tue Apr 15 15:50:16 UTC 2014
Modified Files: src/sys/kern: kern_exec.c Log Message: exec_loadvm: Isolate stack size calc logic into separate functions. To generate a diff of this commit: cvs rdiff -u -r1.395 -r1.396 src/sys/kern/kern_exec.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_exec.c diff -u src/sys/kern/kern_exec.c:1.395 src/sys/kern/kern_exec.c:1.396 --- src/sys/kern/kern_exec.c:1.395 Mon Apr 14 13:14:38 2014 +++ src/sys/kern/kern_exec.c Tue Apr 15 15:50:16 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.395 2014/04/14 13:14:38 uebayasi Exp $ */ +/* $NetBSD: kern_exec.c,v 1.396 2014/04/15 15:50:16 uebayasi Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.395 2014/04/14 13:14:38 uebayasi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.396 2014/04/15 15:50:16 uebayasi Exp $"); #include "opt_exec.h" #include "opt_execfmt.h" @@ -122,6 +122,8 @@ __KERNEL_RCSID(0, "$NetBSD: kern_exec.c, struct execve_data; +static size_t calcargs(struct execve_data * restrict, const size_t); +static size_t calcstack(struct execve_data * restrict, const size_t); static int copyinargs(struct execve_data * restrict, char * const *, char * const *, execve_fetch_element_t, char **); static int copyinargstrs(struct execve_data * restrict, char * const *, @@ -250,6 +252,7 @@ struct execve_data { char *ed_resolvedpathbuf; size_t ed_ps_strings_sz; int ed_szsigcode; + size_t ed_argslen; long ed_argc; long ed_envc; }; @@ -700,29 +703,10 @@ execve_loadvm(struct lwp *l, const char * Calculate the new stack size. */ - const size_t nargenvptrs = - data->ed_argc + /* char *argv[] */ - 1 + /* \0 */ - data->ed_envc + /* char *env[] */ - 1 + /* \0 */ - epp->ep_esch->es_arglen; /* auxinfo */ - - const size_t ptrsz = (epp->ep_flags & EXEC_32) ? - sizeof(int) : sizeof(char *); - - const size_t argenvstrlen = (char *)ALIGN(dp) - data->ed_argp; - - data->ed_szsigcode = epp->ep_esch->es_emul->e_esigcode - - epp->ep_esch->es_emul->e_sigcode; - - data->ed_ps_strings_sz = (epp->ep_flags & EXEC_32) ? - sizeof(struct ps_strings32) : sizeof(struct ps_strings); - - const size_t aslrgap = #ifdef PAX_ASLR - pax_aslr_active(l) ? (cprng_fast32() % PAGE_SIZE) : 0; +#define ASLR_GAP(l) (pax_aslr_active(l) ? (cprng_fast32() % PAGE_SIZE) : 0) #else - 0; +#define ASLR_GAP(l) 0 #endif #ifdef __MACHINE_STACK_GROWS_UP @@ -736,32 +720,19 @@ execve_loadvm(struct lwp *l, const char #define RTLD_GAP 0 #endif - const size_t argenvlen = - RTLD_GAP + /* reserved for _rtld() */ - sizeof(int) + /* XXX argc in stack is long, not int */ - (nargenvptrs * ptrsz); /* XXX auxinfo multiplied by ptr size? */ + const size_t argenvstrlen = (char *)ALIGN(dp) - data->ed_argp; - const size_t sigcode_psstr_sz = - data->ed_szsigcode + /* sigcode */ - data->ed_ps_strings_sz + /* ps_strings */ - STACK_PTHREADSPACE; /* pthread space */ + data->ed_argslen = calcargs(data, argenvstrlen); - const size_t stacklen = - argenvlen + - argenvstrlen + - aslrgap + - sigcode_psstr_sz; - - /* make the stack "safely" aligned */ - const size_t aligned_stacklen = STACK_LEN_ALIGN(stacklen, STACK_ALIGNBYTES); + const size_t len = calcstack(data, ASLR_GAP(l) + RTLD_GAP); - if (aligned_stacklen > epp->ep_ssize) { + if (len > epp->ep_ssize) { /* in effect, compare to initial limit */ - DPRINTF(("%s: stack limit exceeded %zu\n", __func__, aligned_stacklen)); + DPRINTF(("%s: stack limit exceeded %zu\n", __func__, len)); goto bad; } /* adjust "active stack depth" for process VSZ */ - epp->ep_ssize = aligned_stacklen; + epp->ep_ssize = len; return 0; @@ -1397,6 +1368,53 @@ execve1(struct lwp *l, const char *path, return error; } +static size_t +calcargs(struct execve_data * restrict data, const size_t argenvstrlen) +{ + struct exec_package * const epp = &data->ed_pack; + + const size_t nargenvptrs = + data->ed_argc + /* char *argv[] */ + 1 + /* \0 */ + data->ed_envc + /* char *env[] */ + 1 + /* \0 */ + epp->ep_esch->es_arglen; /* auxinfo */ + + const size_t ptrsz = (epp->ep_flags & EXEC_32) ? + sizeof(int) : sizeof(char *); + + const size_t argenvlen = + sizeof(int) + /* XXX argc in stack is long, not int */ + (nargenvptrs * ptrsz); /* XXX auxinfo multiplied by ptr size? */ + + return argenvlen + argenvstrlen; +} + +static size_t +calcstack(struct execve_data * restrict data, const size_t gaplen) +{ + struct exec_package * const epp = &data->ed_pack; + + data->ed_szsigcode = epp->ep_esch->es_emul->e_esigcode - + epp->ep_esch->es_emul->e_sigcode; + + data->ed_ps_strings_sz = (epp->ep_flags & EXEC_32) ? + sizeof(struct ps_strings32) : sizeof(struct ps_strings); + + const size_t sigcode_psstr_sz = + data->ed_szsigcode + /* sigcode */ + data->ed_ps_strings_sz + /* ps_strings */ + STACK_PTHREADSPACE; /* pthread space */ + + const size_t stacklen = + data->ed_argslen + + gaplen + + sigcode_psstr_sz; + + /* make the stack "safely" aligned */ + return STACK_LEN_ALIGN(stacklen, STACK_ALIGNBYTES); +} + static int copyinargs(struct execve_data * restrict data, char * const *args, char * const *envs, execve_fetch_element_t fetch_element, char **dpp)