From: Eric W. Biederman Date: Sun, 12 Jul 2020 13:23:54 +0000 (-0500) Subject: exec: Factor bprm_stack_limits out of prepare_arg_pages X-Git-Tag: v5.9-rc1~164^2^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d8b9cd549ecf0f3dc8da42ada5f0ce73e8ed5f1e;p=thirdparty%2Flinux.git exec: Factor bprm_stack_limits out of prepare_arg_pages In preparation for implementiong kernel_execve (which will take kernel pointers not userspace pointers) factor out bprm_stack_limits out of prepare_arg_pages. This separates the counting which depends upon the getting data from userspace from the calculations of the stack limits which is usable in kernel_execve. The remove prepare_args_pages and compute bprm->argc and bprm->envc directly in do_execveat_common, before bprm_stack_limits is called. Reviewed-by: Kees Cook Reviewed-by: Christoph Hellwig Link: https://lkml.kernel.org/r/87365u6x60.fsf@x220.int.ebiederm.org Signed-off-by: "Eric W. Biederman" --- diff --git a/fs/exec.c b/fs/exec.c index 50508892fa715..f8135dc149b36 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -448,19 +448,10 @@ static int count(struct user_arg_ptr argv, int max) return i; } -static int prepare_arg_pages(struct linux_binprm *bprm, - struct user_arg_ptr argv, struct user_arg_ptr envp) +static int bprm_stack_limits(struct linux_binprm *bprm) { unsigned long limit, ptr_size; - bprm->argc = count(argv, MAX_ARG_STRINGS); - if (bprm->argc < 0) - return bprm->argc; - - bprm->envc = count(envp, MAX_ARG_STRINGS); - if (bprm->envc < 0) - return bprm->envc; - /* * Limit to 1/4 of the max stack size or 3/4 of _STK_LIM * (whichever is smaller) for the argv+env strings. @@ -1964,7 +1955,17 @@ static int do_execveat_common(int fd, struct filename *filename, goto out_ret; } - retval = prepare_arg_pages(bprm, argv, envp); + retval = count(argv, MAX_ARG_STRINGS); + if (retval < 0) + goto out_free; + bprm->argc = retval; + + retval = count(envp, MAX_ARG_STRINGS); + if (retval < 0) + goto out_free; + bprm->envc = retval; + + retval = bprm_stack_limits(bprm); if (retval < 0) goto out_free;