Hi Eric, Today's linux-next merge of the userns tree got a conflict in kernel/user_namespace.c between commits 3c0411846118 ("switch the rest of proc_ns_operations to working with &...->ns") and 64964528b24e ("make proc_ns_operations work with struct ns_common * instead of void *") from the vfs tree and commit 2b714ea67ed4 ("userns: Add a knob to disable setgroups on a per user namespace basis") from the userns tree. I fixed it up (see below) and can carry the fix as necessary (no action is required). -- Cheers, Stephen Rothwell sfr@xxxxxxxxxxxxxxxx diff --cc kernel/user_namespace.c index 1491ad00388f,1db950ec08ce..000000000000 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@@ -842,12 -851,99 +852,104 @@@ static bool new_idmap_permitted(const s return false; } +static inline struct user_namespace *to_user_ns(struct ns_common *ns) +{ + return container_of(ns, struct user_namespace, ns); +} + + static void *setgroups_m_start(struct seq_file *seq, loff_t *ppos) + { + struct user_namespace *ns = seq->private; + + return (*ppos == 0) ? ns : NULL; + } + + static void *setgroups_m_next(struct seq_file *seq, void *v, loff_t *ppos) + { + ++*ppos; + return NULL; + } + + static void setgroups_m_stop(struct seq_file *seq, void *v) + { + } + + static int setgroups_m_show(struct seq_file *seq, void *v) + { + struct user_namespace *ns = seq->private; + + seq_printf(seq, "%s\n", + test_bit(USERNS_SETGROUPS_ALLOWED, &ns->flags) ? + "allow" : "deny"); + return 0; + } + + const struct seq_operations proc_setgroups_seq_operations = { + .start = setgroups_m_start, + .stop = setgroups_m_stop, + .next = setgroups_m_next, + .show = setgroups_m_show, + }; + + ssize_t proc_setgroups_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) + { + struct seq_file *seq = file->private_data; + struct user_namespace *ns = seq->private; + char kbuf[8], *pos; + bool setgroups_allowed; + ssize_t ret; + + ret = -EACCES; + if (!file_ns_capable(file, ns, CAP_SYS_ADMIN)) + goto out; + + /* Only allow a very narrow range of strings to be written */ + ret = -EINVAL; + if ((*ppos != 0) || (count >= sizeof(kbuf))) + goto out; + + /* What was written? */ + ret = -EFAULT; + if (copy_from_user(kbuf, buf, count)) + goto out; + kbuf[count] = '\0'; + pos = kbuf; + + /* What is being requested? */ + ret = -EINVAL; + if (strncmp(pos, "allow", 5) == 0) { + pos += 5; + setgroups_allowed = true; + } + else if (strncmp(pos, "deny", 4) == 0) { + pos += 4; + setgroups_allowed = false; + } + else + goto out; + + /* Verify there is not trailing junk on the line */ + pos = skip_spaces(pos); + if (*pos != '\0') + goto out; + + if (setgroups_allowed) { + ret = -EPERM; + if (!userns_setgroups_allowed(ns)) + goto out; + } else { + userns_disable_setgroups(ns); + } + + /* Report a successful write */ + *ppos = count; + ret = count; + out: + return ret; + } + -static void *userns_get(struct task_struct *task) +static struct ns_common *userns_get(struct task_struct *task) { struct user_namespace *user_ns;
Attachment:
pgpeB4l1D0adl.pgp
Description: OpenPGP digital signature