Commit ddf75ae3 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull namespace fixes from Eric Biederman:
 "This tree includes two bug fixes for problems Oleg spotted on his
  review of the recent pid namespace work.  A small fix to not enable
  bottom halves with irqs disabled, and a trivial build fix for f2fs
  with user namespaces enabled."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
  f2fs: Don't assign e_id in f2fs_acl_from_disk
  proc: Allow proc_free_inum to be called from any context
  pidns: Stop pid allocation when init dies
  pidns: Outlaw thread creation after unshare(CLONE_NEWPID)
parents 7fd83b47 48c6d121
...@@ -82,7 +82,6 @@ static struct posix_acl *f2fs_acl_from_disk(const char *value, size_t size) ...@@ -82,7 +82,6 @@ static struct posix_acl *f2fs_acl_from_disk(const char *value, size_t size)
case ACL_GROUP_OBJ: case ACL_GROUP_OBJ:
case ACL_MASK: case ACL_MASK:
case ACL_OTHER: case ACL_OTHER:
acl->a_entries[i].e_id = ACL_UNDEFINED_ID;
entry = (struct f2fs_acl_entry *)((char *)entry + entry = (struct f2fs_acl_entry *)((char *)entry +
sizeof(struct f2fs_acl_entry_short)); sizeof(struct f2fs_acl_entry_short));
break; break;
......
...@@ -352,18 +352,18 @@ int proc_alloc_inum(unsigned int *inum) ...@@ -352,18 +352,18 @@ int proc_alloc_inum(unsigned int *inum)
if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL)) if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL))
return -ENOMEM; return -ENOMEM;
spin_lock_bh(&proc_inum_lock); spin_lock_irq(&proc_inum_lock);
error = ida_get_new(&proc_inum_ida, &i); error = ida_get_new(&proc_inum_ida, &i);
spin_unlock_bh(&proc_inum_lock); spin_unlock_irq(&proc_inum_lock);
if (error == -EAGAIN) if (error == -EAGAIN)
goto retry; goto retry;
else if (error) else if (error)
return error; return error;
if (i > UINT_MAX - PROC_DYNAMIC_FIRST) { if (i > UINT_MAX - PROC_DYNAMIC_FIRST) {
spin_lock_bh(&proc_inum_lock); spin_lock_irq(&proc_inum_lock);
ida_remove(&proc_inum_ida, i); ida_remove(&proc_inum_ida, i);
spin_unlock_bh(&proc_inum_lock); spin_unlock_irq(&proc_inum_lock);
return -ENOSPC; return -ENOSPC;
} }
*inum = PROC_DYNAMIC_FIRST + i; *inum = PROC_DYNAMIC_FIRST + i;
...@@ -372,9 +372,10 @@ int proc_alloc_inum(unsigned int *inum) ...@@ -372,9 +372,10 @@ int proc_alloc_inum(unsigned int *inum)
void proc_free_inum(unsigned int inum) void proc_free_inum(unsigned int inum)
{ {
spin_lock_bh(&proc_inum_lock); unsigned long flags;
spin_lock_irqsave(&proc_inum_lock, flags);
ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST); ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST);
spin_unlock_bh(&proc_inum_lock); spin_unlock_irqrestore(&proc_inum_lock, flags);
} }
static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd) static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
......
...@@ -121,6 +121,7 @@ int next_pidmap(struct pid_namespace *pid_ns, unsigned int last); ...@@ -121,6 +121,7 @@ int next_pidmap(struct pid_namespace *pid_ns, unsigned int last);
extern struct pid *alloc_pid(struct pid_namespace *ns); extern struct pid *alloc_pid(struct pid_namespace *ns);
extern void free_pid(struct pid *pid); extern void free_pid(struct pid *pid);
extern void disable_pid_allocation(struct pid_namespace *ns);
/* /*
* ns_of_pid() returns the pid namespace in which the specified pid was * ns_of_pid() returns the pid namespace in which the specified pid was
......
...@@ -21,7 +21,7 @@ struct pid_namespace { ...@@ -21,7 +21,7 @@ struct pid_namespace {
struct kref kref; struct kref kref;
struct pidmap pidmap[PIDMAP_ENTRIES]; struct pidmap pidmap[PIDMAP_ENTRIES];
int last_pid; int last_pid;
int nr_hashed; unsigned int nr_hashed;
struct task_struct *child_reaper; struct task_struct *child_reaper;
struct kmem_cache *pid_cachep; struct kmem_cache *pid_cachep;
unsigned int level; unsigned int level;
...@@ -42,6 +42,8 @@ struct pid_namespace { ...@@ -42,6 +42,8 @@ struct pid_namespace {
extern struct pid_namespace init_pid_ns; extern struct pid_namespace init_pid_ns;
#define PIDNS_HASH_ADDING (1U << 31)
#ifdef CONFIG_PID_NS #ifdef CONFIG_PID_NS
static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns) static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
{ {
......
...@@ -1166,6 +1166,14 @@ static struct task_struct *copy_process(unsigned long clone_flags, ...@@ -1166,6 +1166,14 @@ static struct task_struct *copy_process(unsigned long clone_flags,
current->signal->flags & SIGNAL_UNKILLABLE) current->signal->flags & SIGNAL_UNKILLABLE)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
/*
* If the new process will be in a different pid namespace
* don't allow the creation of threads.
*/
if ((clone_flags & (CLONE_VM|CLONE_NEWPID)) &&
(task_active_pid_ns(current) != current->nsproxy->pid_ns))
return ERR_PTR(-EINVAL);
retval = security_task_create(clone_flags); retval = security_task_create(clone_flags);
if (retval) if (retval)
goto fork_out; goto fork_out;
......
...@@ -270,7 +270,6 @@ void free_pid(struct pid *pid) ...@@ -270,7 +270,6 @@ void free_pid(struct pid *pid)
wake_up_process(ns->child_reaper); wake_up_process(ns->child_reaper);
break; break;
case 0: case 0:
ns->nr_hashed = -1;
schedule_work(&ns->proc_work); schedule_work(&ns->proc_work);
break; break;
} }
...@@ -319,7 +318,7 @@ struct pid *alloc_pid(struct pid_namespace *ns) ...@@ -319,7 +318,7 @@ struct pid *alloc_pid(struct pid_namespace *ns)
upid = pid->numbers + ns->level; upid = pid->numbers + ns->level;
spin_lock_irq(&pidmap_lock); spin_lock_irq(&pidmap_lock);
if (ns->nr_hashed < 0) if (!(ns->nr_hashed & PIDNS_HASH_ADDING))
goto out_unlock; goto out_unlock;
for ( ; upid >= pid->numbers; --upid) { for ( ; upid >= pid->numbers; --upid) {
hlist_add_head_rcu(&upid->pid_chain, hlist_add_head_rcu(&upid->pid_chain,
...@@ -342,6 +341,13 @@ struct pid *alloc_pid(struct pid_namespace *ns) ...@@ -342,6 +341,13 @@ struct pid *alloc_pid(struct pid_namespace *ns)
goto out; goto out;
} }
void disable_pid_allocation(struct pid_namespace *ns)
{
spin_lock_irq(&pidmap_lock);
ns->nr_hashed &= ~PIDNS_HASH_ADDING;
spin_unlock_irq(&pidmap_lock);
}
struct pid *find_pid_ns(int nr, struct pid_namespace *ns) struct pid *find_pid_ns(int nr, struct pid_namespace *ns)
{ {
struct hlist_node *elem; struct hlist_node *elem;
...@@ -573,6 +579,9 @@ void __init pidhash_init(void) ...@@ -573,6 +579,9 @@ void __init pidhash_init(void)
void __init pidmap_init(void) void __init pidmap_init(void)
{ {
/* Veryify no one has done anything silly */
BUILD_BUG_ON(PID_MAX_LIMIT >= PIDNS_HASH_ADDING);
/* bump default and minimum pid_max based on number of cpus */ /* bump default and minimum pid_max based on number of cpus */
pid_max = min(pid_max_max, max_t(int, pid_max, pid_max = min(pid_max_max, max_t(int, pid_max,
PIDS_PER_CPU_DEFAULT * num_possible_cpus())); PIDS_PER_CPU_DEFAULT * num_possible_cpus()));
...@@ -584,7 +593,7 @@ void __init pidmap_init(void) ...@@ -584,7 +593,7 @@ void __init pidmap_init(void)
/* Reserve PID 0. We never call free_pidmap(0) */ /* Reserve PID 0. We never call free_pidmap(0) */
set_bit(0, init_pid_ns.pidmap[0].page); set_bit(0, init_pid_ns.pidmap[0].page);
atomic_dec(&init_pid_ns.pidmap[0].nr_free); atomic_dec(&init_pid_ns.pidmap[0].nr_free);
init_pid_ns.nr_hashed = 1; init_pid_ns.nr_hashed = PIDNS_HASH_ADDING;
init_pid_ns.pid_cachep = KMEM_CACHE(pid, init_pid_ns.pid_cachep = KMEM_CACHE(pid,
SLAB_HWCACHE_ALIGN | SLAB_PANIC); SLAB_HWCACHE_ALIGN | SLAB_PANIC);
......
...@@ -115,6 +115,7 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns ...@@ -115,6 +115,7 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
ns->level = level; ns->level = level;
ns->parent = get_pid_ns(parent_pid_ns); ns->parent = get_pid_ns(parent_pid_ns);
ns->user_ns = get_user_ns(user_ns); ns->user_ns = get_user_ns(user_ns);
ns->nr_hashed = PIDNS_HASH_ADDING;
INIT_WORK(&ns->proc_work, proc_cleanup_work); INIT_WORK(&ns->proc_work, proc_cleanup_work);
set_bit(0, ns->pidmap[0].page); set_bit(0, ns->pidmap[0].page);
...@@ -181,6 +182,9 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) ...@@ -181,6 +182,9 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
int rc; int rc;
struct task_struct *task, *me = current; struct task_struct *task, *me = current;
/* Don't allow any more processes into the pid namespace */
disable_pid_allocation(pid_ns);
/* Ignore SIGCHLD causing any terminated children to autoreap */ /* Ignore SIGCHLD causing any terminated children to autoreap */
spin_lock_irq(&me->sighand->siglock); spin_lock_irq(&me->sighand->siglock);
me->sighand->action[SIGCHLD - 1].sa.sa_handler = SIG_IGN; me->sighand->action[SIGCHLD - 1].sa.sa_handler = SIG_IGN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment