Merge branch 'master' into next
Conflicts: fs/namei.c Manually merged per: diff --cc fs/namei.c index 734f2b5,bbc15c2..0000000 --- a/fs/namei.c +++ b/fs/namei.c @@@ -860,9 -848,8 +849,10 @@@ static int __link_path_walk(const char nd->flags |= LOOKUP_CONTINUE; err = exec_permission_lite(inode); if (err == -EAGAIN) - err = vfs_permission(nd, MAY_EXEC); + err = inode_permission(nd->path.dentry->d_inode, + MAY_EXEC); + if (!err) + err = ima_path_check(&nd->path, MAY_EXEC); if (err) break; @@@ -1525,14 -1506,9 +1509,14 @@@ int may_open(struct path *path, int acc flag &= ~O_TRUNC; } - error = vfs_permission(nd, acc_mode); + error = inode_permission(inode, acc_mode); if (error) return error; + - error = ima_path_check(&nd->path, ++ error = ima_path_check(path, + acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); + if (error) + return error; /* * An append-only file must be opened in append mode for writing. */ Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
80
fs/exec.c
80
fs/exec.c
@@ -52,17 +52,13 @@
|
||||
#include <linux/audit.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/fsnotify.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/tlb.h>
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef __alpha__
|
||||
/* for /sbin/loader handling in search_binary_handler() */
|
||||
#include <linux/a.out.h>
|
||||
#endif
|
||||
|
||||
int core_uses_pid;
|
||||
char core_pattern[CORENAME_MAX_SIZE] = "core";
|
||||
int suid_dumpable = 0;
|
||||
@@ -104,7 +100,7 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
|
||||
*
|
||||
* Also note that we take the address to load from from the file itself.
|
||||
*/
|
||||
asmlinkage long sys_uselib(const char __user * library)
|
||||
SYSCALL_DEFINE1(uselib, const char __user *, library)
|
||||
{
|
||||
struct file *file;
|
||||
struct nameidata nd;
|
||||
@@ -128,7 +124,8 @@ asmlinkage long sys_uselib(const char __user * library)
|
||||
if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
|
||||
goto exit;
|
||||
|
||||
error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN);
|
||||
error = inode_permission(nd.path.dentry->d_inode,
|
||||
MAY_READ | MAY_EXEC | MAY_OPEN);
|
||||
if (error)
|
||||
goto exit;
|
||||
error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
|
||||
@@ -140,6 +137,8 @@ asmlinkage long sys_uselib(const char __user * library)
|
||||
if (IS_ERR(file))
|
||||
goto out;
|
||||
|
||||
fsnotify_open(file->f_path.dentry);
|
||||
|
||||
error = -ENOEXEC;
|
||||
if(file->f_op) {
|
||||
struct linux_binfmt * fmt;
|
||||
@@ -237,13 +236,13 @@ static void flush_arg_page(struct linux_binprm *bprm, unsigned long pos,
|
||||
|
||||
static int __bprm_mm_init(struct linux_binprm *bprm)
|
||||
{
|
||||
int err = -ENOMEM;
|
||||
int err;
|
||||
struct vm_area_struct *vma = NULL;
|
||||
struct mm_struct *mm = bprm->mm;
|
||||
|
||||
bprm->vma = vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
|
||||
if (!vma)
|
||||
goto err;
|
||||
return -ENOMEM;
|
||||
|
||||
down_write(&mm->mmap_sem);
|
||||
vma->vm_mm = mm;
|
||||
@@ -256,28 +255,20 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
|
||||
*/
|
||||
vma->vm_end = STACK_TOP_MAX;
|
||||
vma->vm_start = vma->vm_end - PAGE_SIZE;
|
||||
|
||||
vma->vm_flags = VM_STACK_FLAGS;
|
||||
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
|
||||
err = insert_vm_struct(mm, vma);
|
||||
if (err) {
|
||||
up_write(&mm->mmap_sem);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
|
||||
mm->stack_vm = mm->total_vm = 1;
|
||||
up_write(&mm->mmap_sem);
|
||||
|
||||
bprm->p = vma->vm_end - sizeof(void *);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (vma) {
|
||||
bprm->vma = NULL;
|
||||
kmem_cache_free(vm_area_cachep, vma);
|
||||
}
|
||||
|
||||
up_write(&mm->mmap_sem);
|
||||
bprm->vma = NULL;
|
||||
kmem_cache_free(vm_area_cachep, vma);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -684,7 +675,7 @@ struct file *open_exec(const char *name)
|
||||
if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
|
||||
goto out_path_put;
|
||||
|
||||
err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN);
|
||||
err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
|
||||
if (err)
|
||||
goto out_path_put;
|
||||
err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
|
||||
@@ -695,6 +686,8 @@ struct file *open_exec(const char *name)
|
||||
if (IS_ERR(file))
|
||||
return file;
|
||||
|
||||
fsnotify_open(file->f_path.dentry);
|
||||
|
||||
err = deny_write_access(file);
|
||||
if (err) {
|
||||
fput(file);
|
||||
@@ -1178,41 +1171,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||
unsigned int depth = bprm->recursion_depth;
|
||||
int try,retval;
|
||||
struct linux_binfmt *fmt;
|
||||
#ifdef __alpha__
|
||||
/* handle /sbin/loader.. */
|
||||
{
|
||||
struct exec * eh = (struct exec *) bprm->buf;
|
||||
|
||||
if (!bprm->loader && eh->fh.f_magic == 0x183 &&
|
||||
(eh->fh.f_flags & 0x3000) == 0x3000)
|
||||
{
|
||||
struct file * file;
|
||||
unsigned long loader;
|
||||
|
||||
allow_write_access(bprm->file);
|
||||
fput(bprm->file);
|
||||
bprm->file = NULL;
|
||||
|
||||
loader = bprm->vma->vm_end - sizeof(void *);
|
||||
|
||||
file = open_exec("/sbin/loader");
|
||||
retval = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
return retval;
|
||||
|
||||
/* Remember if the application is TASO. */
|
||||
bprm->taso = eh->ah.entry < 0x100000000UL;
|
||||
|
||||
bprm->file = file;
|
||||
bprm->loader = loader;
|
||||
retval = prepare_binprm(bprm);
|
||||
if (retval<0)
|
||||
return retval;
|
||||
/* should call search_binary_handler recursively here,
|
||||
but it does not matter */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
retval = security_bprm_check(bprm);
|
||||
if (retval)
|
||||
return retval;
|
||||
@@ -1737,7 +1696,7 @@ int get_dumpable(struct mm_struct *mm)
|
||||
return (ret >= 2) ? 2 : ret;
|
||||
}
|
||||
|
||||
int do_coredump(long signr, int exit_code, struct pt_regs * regs)
|
||||
void do_coredump(long signr, int exit_code, struct pt_regs *regs)
|
||||
{
|
||||
struct core_state core_state;
|
||||
char corename[CORENAME_MAX_SIZE + 1];
|
||||
@@ -1821,6 +1780,11 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
|
||||
|
||||
if (ispipe) {
|
||||
helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
|
||||
if (!helper_argv) {
|
||||
printk(KERN_WARNING "%s failed to allocate memory\n",
|
||||
__func__);
|
||||
goto fail_unlock;
|
||||
}
|
||||
/* Terminate the string before the first option */
|
||||
delimit = strchr(corename, ' ');
|
||||
if (delimit)
|
||||
@@ -1888,5 +1852,5 @@ fail_unlock:
|
||||
put_cred(cred);
|
||||
coredump_finish(mm);
|
||||
fail:
|
||||
return retval;
|
||||
return;
|
||||
}
|
||||
|
Reference in New Issue
Block a user