diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/fs/exec.c b/fs/exec.c index e87e3c020c61..0d4986aec449 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1028,7 +1028,7 @@ static int exec_mmap(struct mm_struct *mm) } } task_lock(tsk); - + preempt_disable_rt(); local_irq_disable(); active_mm = tsk->active_mm; tsk->active_mm = mm; @@ -1047,6 +1047,7 @@ static int exec_mmap(struct mm_struct *mm) local_irq_enable(); tsk->mm->vmacache_seqnum = 0; vmacache_flush(tsk); + preempt_enable_rt(); task_unlock(tsk); if (old_mm) { up_read(&old_mm->mmap_sem); @@ -1805,6 +1806,9 @@ static int __do_execve_file(int fd, struct filename *filename, goto out_unmark; bprm->argc = count(argv, MAX_ARG_STRINGS); + if (bprm->argc == 0) + pr_warn_once("process '%s' launched '%s' with NULL argv: empty string added\n", + current->comm, bprm->filename); if ((retval = bprm->argc) < 0) goto out; @@ -1829,6 +1833,20 @@ static int __do_execve_file(int fd, struct filename *filename, if (retval < 0) goto out; + /* + * When argv is empty, add an empty string ("") as argv[0] to + * ensure confused userspace programs that start processing + * from argv[1] won't end up walking envp. See also + * bprm_stack_limits(). + */ + if (bprm->argc == 0) { + const char *argv[] = { "", NULL }; + retval = copy_strings_kernel(1, argv, bprm); + if (retval < 0) + goto out; + bprm->argc = 1; + } + retval = exec_binprm(bprm); if (retval < 0) goto out; |