mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
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)
This commit is contained in:
commit
ddf75ae34e
7 changed files with 35 additions and 11 deletions
|
@ -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 @@ retry:
|
||||||
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 @@ retry:
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
|
|
||||||
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,
|
||||||
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;
|
||||||
|
|
15
kernel/pid.c
15
kernel/pid.c
|
@ -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)
|
||||||
|
|
||||||
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 @@ out_free:
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
/* 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
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue