Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
Remove two unneeded exports and make two symbols static in fs/mpage.c
Cleanup after commit 585d3bc06f
Trim includes of fdtable.h
Don't crap into descriptor table in binfmt_som
Trim includes in binfmt_elf
Don't mess with descriptor table in load_elf_binary()
Get rid of indirect include of fs_struct.h
New helper - current_umask()
check_unsafe_exec() doesn't care about signal handlers sharing
New locking/refcounting for fs_struct
Take fs_struct handling to new file (fs/fs_struct.c)
Get rid of bumping fs_struct refcount in pivot_root(2)
Kill unsharing fs_struct in __set_personality()
This commit is contained in:
@@ -66,6 +66,7 @@
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/inotify.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/fs_struct.h>
|
||||
|
||||
#include "audit.h"
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/fs_struct.h>
|
||||
|
||||
|
||||
static void default_handler(int, struct pt_regs *);
|
||||
@@ -145,28 +146,6 @@ __set_personality(u_long personality)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (atomic_read(¤t->fs->count) != 1) {
|
||||
struct fs_struct *fsp, *ofsp;
|
||||
|
||||
fsp = copy_fs_struct(current->fs);
|
||||
if (fsp == NULL) {
|
||||
module_put(ep->module);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
task_lock(current);
|
||||
ofsp = current->fs;
|
||||
current->fs = fsp;
|
||||
task_unlock(current);
|
||||
|
||||
put_fs_struct(ofsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* At that point we are guaranteed to be the sole owner of
|
||||
* current->fs.
|
||||
*/
|
||||
|
||||
current->personality = personality;
|
||||
oep = current_thread_info()->exec_domain;
|
||||
current_thread_info()->exec_domain = ep;
|
||||
|
@@ -46,6 +46,7 @@
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/task_io_accounting_ops.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/fs_struct.h>
|
||||
#include <linux/init_task.h>
|
||||
#include <trace/sched.h>
|
||||
|
||||
@@ -420,7 +421,6 @@ EXPORT_SYMBOL(disallow_signal);
|
||||
void daemonize(const char *name, ...)
|
||||
{
|
||||
va_list args;
|
||||
struct fs_struct *fs;
|
||||
sigset_t blocked;
|
||||
|
||||
va_start(args, name);
|
||||
@@ -453,11 +453,7 @@ void daemonize(const char *name, ...)
|
||||
|
||||
/* Become as one with the init task */
|
||||
|
||||
exit_fs(current); /* current->fs->count--; */
|
||||
fs = init_task.fs;
|
||||
current->fs = fs;
|
||||
atomic_inc(&fs->count);
|
||||
|
||||
daemonize_fs_struct();
|
||||
exit_files(current);
|
||||
current->files = init_task.files;
|
||||
atomic_inc(¤t->files->count);
|
||||
@@ -556,30 +552,6 @@ void exit_files(struct task_struct *tsk)
|
||||
}
|
||||
}
|
||||
|
||||
void put_fs_struct(struct fs_struct *fs)
|
||||
{
|
||||
/* No need to hold fs->lock if we are killing it */
|
||||
if (atomic_dec_and_test(&fs->count)) {
|
||||
path_put(&fs->root);
|
||||
path_put(&fs->pwd);
|
||||
kmem_cache_free(fs_cachep, fs);
|
||||
}
|
||||
}
|
||||
|
||||
void exit_fs(struct task_struct *tsk)
|
||||
{
|
||||
struct fs_struct * fs = tsk->fs;
|
||||
|
||||
if (fs) {
|
||||
task_lock(tsk);
|
||||
tsk->fs = NULL;
|
||||
task_unlock(tsk);
|
||||
put_fs_struct(fs);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(exit_fs);
|
||||
|
||||
#ifdef CONFIG_MM_OWNER
|
||||
/*
|
||||
* Task p is exiting and it owned mm, lets find a new owner for it
|
||||
|
@@ -60,6 +60,7 @@
|
||||
#include <linux/tty.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/fs_struct.h>
|
||||
#include <trace/sched.h>
|
||||
#include <linux/magic.h>
|
||||
|
||||
@@ -681,38 +682,21 @@ fail_nomem:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct fs_struct *__copy_fs_struct(struct fs_struct *old)
|
||||
{
|
||||
struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
|
||||
/* We don't need to lock fs - think why ;-) */
|
||||
if (fs) {
|
||||
atomic_set(&fs->count, 1);
|
||||
rwlock_init(&fs->lock);
|
||||
fs->umask = old->umask;
|
||||
read_lock(&old->lock);
|
||||
fs->root = old->root;
|
||||
path_get(&old->root);
|
||||
fs->pwd = old->pwd;
|
||||
path_get(&old->pwd);
|
||||
read_unlock(&old->lock);
|
||||
}
|
||||
return fs;
|
||||
}
|
||||
|
||||
struct fs_struct *copy_fs_struct(struct fs_struct *old)
|
||||
{
|
||||
return __copy_fs_struct(old);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(copy_fs_struct);
|
||||
|
||||
static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
|
||||
{
|
||||
struct fs_struct *fs = current->fs;
|
||||
if (clone_flags & CLONE_FS) {
|
||||
atomic_inc(¤t->fs->count);
|
||||
/* tsk->fs is already what we want */
|
||||
write_lock(&fs->lock);
|
||||
if (fs->in_exec) {
|
||||
write_unlock(&fs->lock);
|
||||
return -EAGAIN;
|
||||
}
|
||||
fs->users++;
|
||||
write_unlock(&fs->lock);
|
||||
return 0;
|
||||
}
|
||||
tsk->fs = __copy_fs_struct(current->fs);
|
||||
tsk->fs = copy_fs_struct(fs);
|
||||
if (!tsk->fs)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
@@ -1544,12 +1528,16 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
|
||||
{
|
||||
struct fs_struct *fs = current->fs;
|
||||
|
||||
if ((unshare_flags & CLONE_FS) &&
|
||||
(fs && atomic_read(&fs->count) > 1)) {
|
||||
*new_fsp = __copy_fs_struct(current->fs);
|
||||
if (!*new_fsp)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!(unshare_flags & CLONE_FS) || !fs)
|
||||
return 0;
|
||||
|
||||
/* don't need lock here; in the worst case we'll do useless copy */
|
||||
if (fs->users == 1)
|
||||
return 0;
|
||||
|
||||
*new_fsp = copy_fs_struct(fs);
|
||||
if (!*new_fsp)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1665,8 +1653,13 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
|
||||
|
||||
if (new_fs) {
|
||||
fs = current->fs;
|
||||
write_lock(&fs->lock);
|
||||
current->fs = new_fs;
|
||||
new_fs = fs;
|
||||
if (--fs->users)
|
||||
new_fs = NULL;
|
||||
else
|
||||
new_fs = fs;
|
||||
write_unlock(&fs->lock);
|
||||
}
|
||||
|
||||
if (new_mm) {
|
||||
@@ -1705,7 +1698,7 @@ bad_unshare_cleanup_sigh:
|
||||
|
||||
bad_unshare_cleanup_fs:
|
||||
if (new_fs)
|
||||
put_fs_struct(new_fs);
|
||||
free_fs_struct(new_fs);
|
||||
|
||||
bad_unshare_cleanup_thread:
|
||||
bad_unshare_out:
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/fs_struct.h>
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
Reference in New Issue
Block a user