diff options
| author | 2016-11-01 09:17:57 +0000 | |
|---|---|---|
| committer | 2016-11-01 09:17:57 +0000 | |
| commit | 9902aa4728fe9128ea45f1a772e2238d64d8cdc5 (patch) | |
| tree | cca30efb3ad2126fcb10aa6349ed799a5656e851 /fs/exec.c | |
| parent | ARM: dts: am335x-boneblack: Add HDMI audio support (diff) | |
| parent | drm/i2c: tda998x: mali-dp: hdlcd: refactor connector registration (diff) | |
Merge branch 'drm-tda998x-mali' into drm-tda998x-devel
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/fs/exec.c b/fs/exec.c index 887c1c955df8..6fcfb3f7b137 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -762,6 +762,39 @@ out_unlock: } EXPORT_SYMBOL(setup_arg_pages); +#else + +/* + * Transfer the program arguments and environment from the holding pages + * onto the stack. The provided stack pointer is adjusted accordingly. + */ +int transfer_args_to_stack(struct linux_binprm *bprm, + unsigned long *sp_location) +{ + unsigned long index, stop, sp; + int ret = 0; + + stop = bprm->p >> PAGE_SHIFT; + sp = *sp_location; + + for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { + unsigned int offset = index == stop ? bprm->p & ~PAGE_MASK : 0; + char *src = kmap(bprm->page[index]) + offset; + sp -= PAGE_SIZE - offset; + if (copy_to_user((void *) sp, src, PAGE_SIZE - offset) != 0) + ret = -EFAULT; + kunmap(bprm->page[index]); + if (ret) + goto out; + } + + *sp_location = sp; + +out: + return ret; +} +EXPORT_SYMBOL(transfer_args_to_stack); + #endif /* CONFIG_MMU */ static struct file *do_open_execat(int fd, struct filename *name, int flags) @@ -866,7 +899,8 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, goto out; } - *buf = vmalloc(i_size); + if (id != READING_FIRMWARE_PREALLOC_BUFFER) + *buf = vmalloc(i_size); if (!*buf) { ret = -ENOMEM; goto out; @@ -897,8 +931,10 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, out_free: if (ret < 0) { - vfree(*buf); - *buf = NULL; + if (id != READING_FIRMWARE_PREALLOC_BUFFER) { + vfree(*buf); + *buf = NULL; + } } out: @@ -1411,7 +1447,7 @@ static void bprm_fill_uid(struct linux_binprm *bprm) bprm->cred->euid = current_euid(); bprm->cred->egid = current_egid(); - if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) + if (!mnt_may_suid(bprm->file->f_path.mnt)) return; if (task_no_new_privs(current)) |
