Merge branch 'linus' into perfcounters/core-v2
Merge reason: we have gathered quite a few conflicts, need to merge upstream Conflicts: arch/powerpc/kernel/Makefile arch/x86/ia32/ia32entry.S arch/x86/include/asm/hardirq.h arch/x86/include/asm/unistd_32.h arch/x86/include/asm/unistd_64.h arch/x86/kernel/cpu/common.c arch/x86/kernel/irq.c arch/x86/kernel/syscall_table_32.S arch/x86/mm/iomap_32.c include/linux/sched.h kernel/Makefile Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
52
fs/exec.c
52
fs/exec.c
@@ -46,6 +46,7 @@
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/ima.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/tsacct_kern.h>
|
||||
#include <linux/cn_proc.h>
|
||||
@@ -53,6 +54,7 @@
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/fsnotify.h>
|
||||
#include <linux/fs_struct.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/mmu_context.h>
|
||||
@@ -128,6 +130,9 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
|
||||
MAY_READ | MAY_EXEC | MAY_OPEN);
|
||||
if (error)
|
||||
goto exit;
|
||||
error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
|
||||
if (error)
|
||||
goto exit;
|
||||
|
||||
file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
|
||||
error = PTR_ERR(file);
|
||||
@@ -673,6 +678,9 @@ struct file *open_exec(const char *name)
|
||||
goto out_path_put;
|
||||
|
||||
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);
|
||||
if (err)
|
||||
goto out_path_put;
|
||||
|
||||
@@ -1057,32 +1065,35 @@ EXPORT_SYMBOL(install_exec_creds);
|
||||
* - the caller must hold current->cred_exec_mutex to protect against
|
||||
* PTRACE_ATTACH
|
||||
*/
|
||||
void check_unsafe_exec(struct linux_binprm *bprm, struct files_struct *files)
|
||||
int check_unsafe_exec(struct linux_binprm *bprm)
|
||||
{
|
||||
struct task_struct *p = current, *t;
|
||||
unsigned long flags;
|
||||
unsigned n_fs, n_files, n_sighand;
|
||||
unsigned n_fs;
|
||||
int res = 0;
|
||||
|
||||
bprm->unsafe = tracehook_unsafe_exec(p);
|
||||
|
||||
n_fs = 1;
|
||||
n_files = 1;
|
||||
n_sighand = 1;
|
||||
write_lock(&p->fs->lock);
|
||||
lock_task_sighand(p, &flags);
|
||||
for (t = next_thread(p); t != p; t = next_thread(t)) {
|
||||
if (t->fs == p->fs)
|
||||
n_fs++;
|
||||
if (t->files == files)
|
||||
n_files++;
|
||||
n_sighand++;
|
||||
}
|
||||
|
||||
if (atomic_read(&p->fs->count) > n_fs ||
|
||||
atomic_read(&p->files->count) > n_files ||
|
||||
atomic_read(&p->sighand->count) > n_sighand)
|
||||
if (p->fs->users > n_fs) {
|
||||
bprm->unsafe |= LSM_UNSAFE_SHARE;
|
||||
} else {
|
||||
if (p->fs->in_exec)
|
||||
res = -EAGAIN;
|
||||
p->fs->in_exec = 1;
|
||||
}
|
||||
|
||||
unlock_task_sighand(p, &flags);
|
||||
write_unlock(&p->fs->lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1190,6 +1201,9 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||
struct linux_binfmt *fmt;
|
||||
|
||||
retval = security_bprm_check(bprm);
|
||||
if (retval)
|
||||
return retval;
|
||||
retval = ima_bprm_check(bprm);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
@@ -1292,17 +1306,21 @@ int do_execve(char * filename,
|
||||
retval = mutex_lock_interruptible(¤t->cred_exec_mutex);
|
||||
if (retval < 0)
|
||||
goto out_free;
|
||||
current->in_execve = 1;
|
||||
|
||||
retval = -ENOMEM;
|
||||
bprm->cred = prepare_exec_creds();
|
||||
if (!bprm->cred)
|
||||
goto out_unlock;
|
||||
check_unsafe_exec(bprm, displaced);
|
||||
|
||||
retval = check_unsafe_exec(bprm);
|
||||
if (retval)
|
||||
goto out_unlock;
|
||||
|
||||
file = open_exec(filename);
|
||||
retval = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out_unlock;
|
||||
goto out_unmark;
|
||||
|
||||
sched_exec();
|
||||
|
||||
@@ -1345,6 +1363,10 @@ int do_execve(char * filename,
|
||||
goto out;
|
||||
|
||||
/* execve succeeded */
|
||||
write_lock(¤t->fs->lock);
|
||||
current->fs->in_exec = 0;
|
||||
write_unlock(¤t->fs->lock);
|
||||
current->in_execve = 0;
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
acct_update_integrals(current);
|
||||
free_bprm(bprm);
|
||||
@@ -1362,7 +1384,13 @@ out_file:
|
||||
fput(bprm->file);
|
||||
}
|
||||
|
||||
out_unmark:
|
||||
write_lock(¤t->fs->lock);
|
||||
current->fs->in_exec = 0;
|
||||
write_unlock(¤t->fs->lock);
|
||||
|
||||
out_unlock:
|
||||
current->in_execve = 0;
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
|
||||
out_free:
|
||||
|
Reference in New Issue
Block a user