userns: let clone_uts_ns() handle setting uts->user_ns
Subsystems (3)
Serge E. Hallyn
maintainerPATCH 1/4 userns: let clone_uts_ns() handle setting uts->user_ns
To do so we need to pass in the task_struct who'll get the utsname, so we can get its user_ns.
--- include/linux/utsname.h | 10 ++++++---- kernel/nsproxy.c | 7 +------ kernel/utsname.c | 12 +++++++----- 3 files changed, 14 insertions(+), 15 deletions(-)
include/linux/utsname.h +6 -4
@@ -52,8 +52,9 @@ static inline void get_uts_ns(struct uts_namespace *ns)kref_get (&ns->kref); } -extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +extern struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns);extern void free_uts_ns (struct kref *kref);static inline void put_uts_ns (struct uts_namespace *ns)
@@ -69,8 +70,9 @@ static inline void put_uts_ns(struct uts_namespace *ns) { } -static inline struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns) +static inline struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns) {if (flags &CLONE_NEWUTS )return ERR_PTR (-EINVAL );
kernel/nsproxy.c +1 -6
@@ -69,16 +69,11 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_ns; } - new_nsp->uts_ns =copy_utsname (flags, tsk->nsproxy->uts_ns); + new_nsp->uts_ns =copy_utsname (tsk, flags, tsk->nsproxy->uts_ns);if (IS_ERR (new_nsp->uts_ns)) { err =PTR_ERR (new_nsp->uts_ns); goto out_uts; } -if (new_nsp->uts_ns != tsk->nsproxy->uts_ns) { -put_user_ns (new_nsp->uts_ns->user_ns); - new_nsp->uts_ns->user_ns =task_cred_xxx (tsk, user)->user_ns; -get_user_ns (new_nsp->uts_ns->user_ns); - } new_nsp->ipc_ns =copy_ipcs (flags, tsk->nsproxy->ipc_ns);if (IS_ERR (new_nsp->ipc_ns)) {
kernel/utsname.c +7 -5
@@ -31,7 +31,8 @@ static struct uts_namespace *create_uts_ns(void)* @old_ns: namespace to clone * Return NULL on error (failure to kmalloc), new ns otherwise */ -static struct uts_namespace *clone_uts_ns (struct uts_namespace *old_ns) +static struct uts_namespace *clone_uts_ns (struct task_struct *tsk, +struct uts_namespace *old_ns) {struct uts_namespace *ns;
@@ -41,8 +42,7 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)down_read (&uts_sem);memcpy (&ns->name, &old_ns->name,sizeof (ns->name)); - ns->user_ns = old_ns->user_ns; -get_user_ns (ns->user_ns); + ns->user_ns =get_user_ns (task_cred_xxx (tsk, user)->user_ns);up_read (&uts_sem);return ns; }
@@ -53,7 +53,9 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)* utsname of this process won't be seen by parent, and vice * versa. */ -struct uts_namespace *copy_utsname (unsigned long flags,struct uts_namespace *old_ns) +struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *old_ns) {struct uts_namespace *new_ns;
@@ -63,7 +65,7 @@ struct uts_namespace *copy_utsname(unsigned long flags, struct uts_namespace *olif (!(flags &CLONE_NEWUTS ))return old_ns; - new_ns =clone_uts_ns (old_ns); + new_ns =clone_uts_ns (tsk, old_ns);put_uts_ns (old_ns);return new_ns;
Signature · 1 line
1.7.0.4
Serge E. Hallyn
maintainerPATCH 1/4 userns: let clone_uts_ns() handle setting uts->user_ns
To do so we need to pass in the task_struct who'll get the utsname, so we can get its user_ns.
Changelog:
Feb 23: As per Oleg's coment, just pass in tsk.
--- include/linux/utsname.h | 6 +++--- kernel/nsproxy.c | 7 +------ kernel/utsname.c | 12 +++++++----- 3 files changed, 11 insertions(+), 14 deletions(-)
include/linux/utsname.h +3 -3
@@ -53,7 +53,7 @@ static inline void get_uts_ns(struct uts_namespace *ns) }extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +struct task_struct *tsk);extern void free_uts_ns (struct kref *kref);static inline void put_uts_ns (struct uts_namespace *ns)
@@ -70,12 +70,12 @@ static inline void put_uts_ns(struct uts_namespace *ns) }static inline struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns) +struct task_struct *tsk) {if (flags &CLONE_NEWUTS )return ERR_PTR (-EINVAL ); -return ns; +return tsk->nsproxy->uts_ns; }#endif
kernel/nsproxy.c +1 -6
@@ -69,16 +69,11 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_ns; } - new_nsp->uts_ns =copy_utsname (flags, tsk->nsproxy->uts_ns); + new_nsp->uts_ns =copy_utsname (flags, tsk);if (IS_ERR (new_nsp->uts_ns)) { err =PTR_ERR (new_nsp->uts_ns); goto out_uts; } -if (new_nsp->uts_ns != tsk->nsproxy->uts_ns) { -put_user_ns (new_nsp->uts_ns->user_ns); - new_nsp->uts_ns->user_ns =task_cred_xxx (tsk, user)->user_ns; -get_user_ns (new_nsp->uts_ns->user_ns); - } new_nsp->ipc_ns =copy_ipcs (flags, tsk->nsproxy->ipc_ns);if (IS_ERR (new_nsp->ipc_ns)) {
kernel/utsname.c +7 -5
@@ -31,7 +31,8 @@ static struct uts_namespace *create_uts_ns(void)* @old_ns: namespace to clone * Return NULL on error (failure to kmalloc), new ns otherwise */ -static struct uts_namespace *clone_uts_ns (struct uts_namespace *old_ns) +static struct uts_namespace *clone_uts_ns (struct task_struct *tsk, +struct uts_namespace *old_ns) {struct uts_namespace *ns;
@@ -41,8 +42,7 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)down_read (&uts_sem);memcpy (&ns->name, &old_ns->name,sizeof (ns->name)); - ns->user_ns = old_ns->user_ns; -get_user_ns (ns->user_ns); + ns->user_ns =get_user_ns (task_cred_xxx (tsk, user)->user_ns);up_read (&uts_sem);return ns; }
@@ -53,8 +53,10 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)* utsname of this process won't be seen by parent, and vice * versa. */ -struct uts_namespace *copy_utsname (unsigned long flags,struct uts_namespace *old_ns) +struct uts_namespace *copy_utsname (unsigned long flags, +struct task_struct *tsk) { +struct uts_namespace *old_ns = tsk->nsproxy->uts_ns;struct uts_namespace *new_ns;BUG_ON (!old_ns);
@@ -63,7 +65,7 @@ struct uts_namespace *copy_utsname(unsigned long flags, struct uts_namespace *olif (!(flags &CLONE_NEWUTS ))return old_ns; - new_ns =clone_uts_ns (old_ns); + new_ns =clone_uts_ns (tsk, old_ns);put_uts_ns (old_ns);return new_ns;
Signature · 1 line
1.7.0.4
A message that is not in the archive (sent off-list or not yet received): [email protected]
Daniel Lezcano
Acked-byQuoted 7 lines · Serge E. Hallyn
To do so we need to pass in the
task_structwho'll get the utsname, so we can get itsuser_ns.Changelog:
Feb 23: As per Oleg's coment, just pass in tsk.Signed-off-by Serge E. Hallyn<[email protected]>
Quoted 7 lines · Serge E. Hallyn
To do so we need to pass in the
task_structwho'll get the utsname, so we can get itsuser_ns.Changelog:
Feb 23: As per Oleg's coment, just pass in tsk.Signed-off-by Serge E. Hallyn<[email protected]>
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/4 userns: let clone_uts_ns() handle setting uts->user_ns
To do so we need to pass in the task_struct who'll get the utsname, so we can get its user_ns.
Changelog:
Feb 23: As per Oleg's coment, just pass in tsk.
--- include/linux/utsname.h | 6 +++--- kernel/nsproxy.c | 7 +------ kernel/utsname.c | 12 +++++++----- 3 files changed, 11 insertions(+), 14 deletions(-)
include/linux/utsname.h +3 -3
@@ -53,7 +53,7 @@ static inline void get_uts_ns(struct uts_namespace *ns) }extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +struct task_struct *tsk);extern void free_uts_ns (struct kref *kref);static inline void put_uts_ns (struct uts_namespace *ns)
@@ -70,12 +70,12 @@ static inline void put_uts_ns(struct uts_namespace *ns) }static inline struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns) +struct task_struct *tsk) {if (flags &CLONE_NEWUTS )return ERR_PTR (-EINVAL ); -return ns; +return tsk->nsproxy->uts_ns; }#endif
kernel/nsproxy.c +1 -6
@@ -69,16 +69,11 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_ns; } - new_nsp->uts_ns =copy_utsname (flags, tsk->nsproxy->uts_ns); + new_nsp->uts_ns =copy_utsname (flags, tsk);if (IS_ERR (new_nsp->uts_ns)) { err =PTR_ERR (new_nsp->uts_ns); goto out_uts; } -if (new_nsp->uts_ns != tsk->nsproxy->uts_ns) { -put_user_ns (new_nsp->uts_ns->user_ns); - new_nsp->uts_ns->user_ns =task_cred_xxx (tsk, user)->user_ns; -get_user_ns (new_nsp->uts_ns->user_ns); - } new_nsp->ipc_ns =copy_ipcs (flags, tsk->nsproxy->ipc_ns);if (IS_ERR (new_nsp->ipc_ns)) {
kernel/utsname.c +7 -5
@@ -31,7 +31,8 @@ static struct uts_namespace *create_uts_ns(void)* @old_ns: namespace to clone * Return NULL on error (failure to kmalloc), new ns otherwise */ -static struct uts_namespace *clone_uts_ns (struct uts_namespace *old_ns) +static struct uts_namespace *clone_uts_ns (struct task_struct *tsk, +struct uts_namespace *old_ns) {struct uts_namespace *ns;
@@ -41,8 +42,7 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)down_read (&uts_sem);memcpy (&ns->name, &old_ns->name,sizeof (ns->name)); - ns->user_ns = old_ns->user_ns; -get_user_ns (ns->user_ns); + ns->user_ns =get_user_ns (task_cred_xxx (tsk, user)->user_ns);up_read (&uts_sem);return ns; }
@@ -53,8 +53,10 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)* utsname of this process won't be seen by parent, and vice * versa. */ -struct uts_namespace *copy_utsname (unsigned long flags,struct uts_namespace *old_ns) +struct uts_namespace *copy_utsname (unsigned long flags, +struct task_struct *tsk) { +struct uts_namespace *old_ns = tsk->nsproxy->uts_ns;struct uts_namespace *new_ns;BUG_ON (!old_ns);
@@ -63,7 +65,7 @@ struct uts_namespace *copy_utsname(unsigned long flags, struct uts_namespace *olif (!(flags &CLONE_NEWUTS ))return old_ns; - new_ns =clone_uts_ns (old_ns); + new_ns =clone_uts_ns (tsk, old_ns);put_uts_ns (old_ns);return new_ns;
Signature · 1 line
1.7.0.4
PATCH 2/4 userns: let copy_ipcs handle setting ipc_ns->user_ns
In reply to a message not in the archiveTo do that, we have to pass in the task_struct of the task which will own the ipc_ns, so we can assign its user_ns.
--- include/linux/ipc_namespace.h | 8 +++++--- ipc/namespace.c | 12 +++++++----- kernel/nsproxy.c | 7 +------ 3 files changed, 13 insertions(+), 14 deletions(-)
include/linux/ipc_namespace.h +5 -3
@@ -92,7 +92,8 @@ static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; }#endif #if defined(CONFIG_IPC_NS ) -extern struct ipc_namespace *copy_ipcs (unsigned long flags, +extern struct ipc_namespace *copy_ipcs (struct task_struct *tsk, +unsigned long flags,struct ipc_namespace *ns);static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) {
@@ -103,8 +104,9 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)extern void put_ipc_ns (struct ipc_namespace *ns);#else -static inline struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns) +static inline struct ipc_namespace *copy_ipcs (struct task_struct *tsk, +unsigned long flags, +struct ipc_namespace *ns) {if (flags &CLONE_NEWIPC )return ERR_PTR (-EINVAL );
ipc/namespace.c +7 -5
@@ -15,7 +15,8 @@#include "util.h" -static struct ipc_namespace *create_ipc_ns (struct ipc_namespace *old_ns) +static struct ipc_namespace *create_ipc_ns (struct task_struct *tsk, +struct ipc_namespace *old_ns) {struct ipc_namespace *ns;int err;
@@ -44,17 +45,18 @@ static struct ipc_namespace *create_ipc_ns(struct ipc_namespace *old_ns)ipcns_notify (IPCNS_CREATED );register_ipcns_notifier (ns); - ns->user_ns = old_ns->user_ns; -get_user_ns (ns->user_ns); + ns->user_ns =get_user_ns (task_cred_xxx (tsk, user)->user_ns);return ns; } -struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) +struct ipc_namespace *copy_ipcs (struct task_struct *tsk, +unsigned long flags, +struct ipc_namespace *ns) {if (!(flags &CLONE_NEWIPC ))return get_ipc_ns (ns); -return create_ipc_ns (ns); +return create_ipc_ns (tsk, ns); }/*
kernel/nsproxy.c +1 -6
@@ -75,16 +75,11 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_uts; } - new_nsp->ipc_ns =copy_ipcs (flags, tsk->nsproxy->ipc_ns); + new_nsp->ipc_ns =copy_ipcs (tsk, flags, tsk->nsproxy->ipc_ns);if (IS_ERR (new_nsp->ipc_ns)) { err =PTR_ERR (new_nsp->ipc_ns); goto out_ipc; } -if (new_nsp->ipc_ns != tsk->nsproxy->ipc_ns) { -put_user_ns (new_nsp->ipc_ns->user_ns); - new_nsp->ipc_ns->user_ns =task_cred_xxx (tsk, user)->user_ns; -get_user_ns (new_nsp->ipc_ns->user_ns); - } new_nsp->pid_ns =copy_pid_ns (flags,task_active_pid_ns (tsk));if (IS_ERR (new_nsp->pid_ns)) {
Signature · 1 line
1.7.0.4
PATCH 3/4 Add the required user_ns parameter to security_capable
In reply to a message not in the archiveFixes a compile failure.
--- drivers/pci/pci-sysfs.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/pci/pci-sysfs.c +1 -1
@@ -369,7 +369,7 @@ pci_read_config(struct file *filp, struct kobject *kobj,u8 *data = (u8 *) buf;/* Several chips lock up trying to read undefined config space */ -if (security_capable (filp->f_cred,CAP_SYS_ADMIN ) ==0 ) { +if (security_capable (&init_user_ns, filp->f_cred,CAP_SYS_ADMIN ) ==0 ) { size = dev->cfg_size; }else if (dev->hdr_type ==PCI_HEADER_TYPE_CARDBUS ) { size =128 ;
Signature · 1 line
1.7.0.4
Quoted 17 lines · Serge E. Hallyn
To do so we need to pass in the
task_structwho'll get the utsname, so we can get itsuser_ns.Signed-off-by Serge E. Hallyn<[email protected]>---
include/linux/utsname.h | 10 ++++++---- kernel/nsproxy.c | 7 +------ kernel/utsname.c | 12 +++++++----- 3 files changed, 14 insertions(+), 15 deletions(-)include/linux/utsname.h +0
-0
include/linux/utsname.h static inline void get_uts_ns(struct uts_namespace *ns) · line 57
Quoted 8 lines
include/linux/utsname.h +3
-2@@ -52,8 +52,9 @@ static inline void get_uts_ns(struct uts_namespace *ns)kref_get (&ns->kref); } -extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +extern struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns);
Why don't we pass 'user_ns' instead of 'tsk' ? that will look semantically clearer for the caller no ?
(example below).
Quoted 20 lines
include/linux/utsname.h +3
-2extern void free_uts_ns (struct kref *kref);static inline void put_uts_ns (struct uts_namespace *ns)@@ -69,8 +70,9 @@ static inline void put_uts_ns(struct uts_namespace *ns) { } -static inline struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns) +static inline struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns) {if (flags&CLONE_NEWUTS )return ERR_PTR (-EINVAL );kernel/nsproxy.c +0
-0
kernel/nsproxy.c static struct nsproxy *create_new_namespaces(unsigned long flags, · line 76
Quoted 9 lines
kernel/nsproxy.c +1
-1@@ -69,16 +69,11 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_ns; } - new_nsp->uts_ns =copy_utsname (flags, tsk->nsproxy->uts_ns); + new_nsp->uts_ns =copy_utsname (tsk, flags, tsk->nsproxy->uts_ns);if (IS_ERR (new_nsp->uts_ns)) { err =PTR_ERR (new_nsp->uts_ns); goto out_uts; }
...
new_nsp->uts_ns = copy_utsname(flags, tsk->nsproxy->uts_ns, task_cred_xxx(tsk, user)->user_ns);
...
Quoted 52 lines
kernel/nsproxy.c +0
-5-if (new_nsp->uts_ns != tsk->nsproxy->uts_ns) { -put_user_ns (new_nsp->uts_ns->user_ns); - new_nsp->uts_ns->user_ns =task_cred_xxx (tsk, user)->user_ns; -get_user_ns (new_nsp->uts_ns->user_ns); - } new_nsp->ipc_ns =copy_ipcs (flags, tsk->nsproxy->ipc_ns);if (IS_ERR (new_nsp->ipc_ns)) {kernel/utsname.c +7
-5@@ -31,7 +31,8 @@ static struct uts_namespace *create_uts_ns(void)* @old_ns: namespace to clone * Return NULL on error (failure to kmalloc), new ns otherwise */ -static struct uts_namespace *clone_uts_ns (struct uts_namespace *old_ns) +static struct uts_namespace *clone_uts_ns (struct task_struct *tsk, +struct uts_namespace *old_ns) {struct uts_namespace *ns;@@ -41,8 +42,7 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)down_read (&uts_sem);memcpy (&ns->name,&old_ns->name,sizeof (ns->name)); - ns->user_ns = old_ns->user_ns; -get_user_ns (ns->user_ns); + ns->user_ns =get_user_ns (task_cred_xxx (tsk, user)->user_ns);up_read (&uts_sem);return ns; }@@ -53,7 +53,9 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)* utsname of this process won't be seen by parent, and vice * versa. */ -struct uts_namespace *copy_utsname (unsigned long flags,struct uts_namespace *old_ns) +struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *old_ns) {struct uts_namespace *new_ns;@@ -63,7 +65,7 @@ struct uts_namespace *copy_utsname(unsigned long flags, struct uts_namespace *olif (!(flags&CLONE_NEWUTS ))return old_ns; - new_ns =clone_uts_ns (old_ns); + new_ns =clone_uts_ns (tsk, old_ns);put_uts_ns (old_ns);return new_ns;
PATCH 4/4 userns: uts and ipc: fix checkpatch warning
In reply to a message not in the archiveAs pointed out by Andrew Morton (and checkpatch), init/version.c (and ipc/msgutil.c) should not have an extern declaration for init_user_ns. Instead, move those to ipc_namespace.h and utsname.h.
--- include/linux/ipc_namespace.h | 3 ++- include/linux/utsname.h | 1 + init/version.c | 1 - ipc/msgutil.c | 2 -- 4 files changed, 3 insertions(+), 4 deletions(-)
include/linux/ipc_namespace.h +2 -1
@@ -15,6 +15,8 @@#define IPCNS_CALLBACK_PRI 0 +struct user_namespace ; +extern struct user_namespace init_user_ns;struct ipc_ids {int in_use;
@@ -24,7 +26,6 @@ struct ipc_ids {struct idr ipcs_idr; }; -struct user_namespace ;struct ipc_namespace {atomic_t count;struct ipc_ids ids[3 ];
include/linux/utsname.h +1 -0
@@ -38,6 +38,7 @@ struct new_utsname {#include <linux/err.h> struct user_namespace ; +extern struct user_namespace init_user_ns;struct uts_namespace {struct kref kref;
init/version.c +0 -1
@@ -21,7 +21,6 @@ extern int version_string(LINUX_VERSION_CODE);int version_string (LINUX_VERSION_CODE );#endif -extern struct user_namespace init_user_ns;struct uts_namespace init_uts_ns = { .kref = { .refcount =ATOMIC_INIT (2 ),
ipc/msgutil.c +0 -2
@@ -20,8 +20,6 @@DEFINE_SPINLOCK (mq_lock); -extern struct user_namespace init_user_ns; -/* * The next 2 defines are here bc this is the only file * compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE
Signature · 1 line
1.7.0.4
[PATCH 5/4] Clean up capability.h and capability.c
In reply to a message not in the archiveConvert macros to functions to let type safety do its thing. Switch some functions from ints to more appropriate bool. Move all forward declarations together to top of the #ifdef __KERNEL__ section. Use kernel-doc format for comments.
Some macros couldn't be converted because they use functions from security.h which sometimes are extern and sometimes static inline, and we don't want to #include security.h in capability.h.
Also add a real current_user_ns function (and convert the existing macro to _current_user_ns() so we can use it in capability.h without #including cred.h.
--- include/linux/capability.h | 38 ++++++++++++++++++++++++++------------ include/linux/cred.h | 4 +++- kernel/capability.c | 20 ++++++++++++-------- kernel/cred.c | 5 +++++ 4 files changed, 46 insertions(+), 21 deletions(-)
include/linux/capability.h +26 -12
@@ -368,6 +368,17 @@ struct cpu_vfs_cap_data {#ifdef __KERNEL__ +struct dentry ; +struct user_namespace ; + +extern struct user_namespace init_user_ns; + +struct user_namespace *current_user_ns (void ); + +extern const kernel_cap_t __cap_empty_set; +extern const kernel_cap_t __cap_full_set; +extern const kernel_cap_t __cap_init_eff_set; +/* * Internal kernel functions only */
@@ -530,10 +541,6 @@ static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a, cap_intersect(permitted, __cap_nfsd_set)); } -extern const kernel_cap_t __cap_empty_set; -extern const kernel_cap_t __cap_full_set; -extern const kernel_cap_t __cap_init_eff_set; -/** * has_capability - Determine if a task has a superior capability available * @t: The task in question
@@ -560,18 +567,25 @@ extern const kernel_cap_t __cap_init_eff_set;* Note that this does not set PF_SUPERPRIV on the task. */ #define has_capability_noaudit (t, cap) \ - (security_real_capable_noaudit((t), &init_user_ns, (cap)) == 0) + (security_real_capable_noaudit((t), &init_user_ns, (cap)) == 0) -struct user_namespace ; -extern struct user_namespace init_user_ns; -extern int capable (int cap); -extern int ns_capable (struct user_namespace *ns,int cap); -extern int task_ns_capable (struct task_struct *t,int cap); +extern bool capable (int cap); +extern bool ns_capable (struct user_namespace *ns,int cap); +extern bool task_ns_capable (struct task_struct *t,int cap); -#define nsown_capable (cap) (ns_capable(current_user_ns(), (cap))) +/** +* nsown_capable - Check superior capability to one's own user_ns +* @cap: The capability in question +* +* Return true if the current task has the given superior capability +* targeted at its own user namespace. +*/ +static inline bool nsown_capable (int cap) +{ +return ns_capable (current_user_ns (), cap); +}/* audit system wants to get cap info from files as well */ -struct dentry ;extern int get_vfs_caps_from_disk (const struct dentry *dentry,struct cpu_vfs_cap_data *cpu_caps);#endif /* __KERNEL__ */
include/linux/cred.h +3 -1
@@ -354,9 +354,11 @@ static inline void put_cred(const struct cred *_cred)#define current_fsgid () (current_cred_xxx(fsgid))#define current_cap () (current_cred_xxx(cap_effective))#define current_user () (current_cred_xxx(user)) -#define current_user_ns () (current_cred_xxx(user)->user_ns) +#define _current_user_ns () (current_cred_xxx(user)->user_ns)#define current_security () (current_cred_xxx(security)) +extern struct user_namespace *current_user_ns (void ); +#define current_uid_gid (_uid, _gid) \ do { \ const struct cred *__cred; \
kernel/capability.c +12 -8
@@ -300,7 +300,7 @@ error:* This sets PF_SUPERPRIV on the task if the capability is available on the * assumption that it's about to be used. */ -int capable (int cap) +bool capable (int cap) {return ns_capable (&init_user_ns, cap); }
@@ -317,7 +317,7 @@ EXPORT_SYMBOL(capable);* This sets PF_SUPERPRIV on the task if the capability is available on the * assumption that it's about to be used. */ -int ns_capable (struct user_namespace *ns,int cap) +bool ns_capable (struct user_namespace *ns,int cap) {if (unlikely (!cap_valid (cap))) {printk (KERN_CRIT "capable() called with invalid cap=%u\n" , cap);
@@ -326,17 +326,21 @@ int ns_capable(struct user_namespace *ns, int cap)if (security_capable (ns,current_cred (), cap) ==0 ) { current->flags |=PF_SUPERPRIV ; -return 1 ; +return true; } -return 0 ; +return false; }EXPORT_SYMBOL (ns_capable); -/* -* does current have capability 'cap' to the user namespace of task -* 't'. Return true if it does, false otherwise. +/** +* task_ns_capable - Determine whether current task has a superior +* capability targeted at a specific task's user namespace. +* @t: The task whose user namespace is targeted. +* @cap: The capability in question. +* +* Return true if it does, false otherwise. */ -int task_ns_capable (struct task_struct *t,int cap) +bool task_ns_capable (struct task_struct *t,int cap) {return ns_capable (task_cred_xxx (t, user)->user_ns, cap); }
kernel/cred.c +5 -0
@@ -741,6 +741,11 @@ int set_create_files_as(struct cred *new, struct inode *inode) }EXPORT_SYMBOL (set_create_files_as); +struct user_namespace *current_user_ns (void ) +{ +return _current_user_ns (); +} +#ifdef CONFIG_DEBUG_CREDENTIALS bool creds_are_invalid (const struct cred *cred)
Signature · 1 line
1.7.0.4
Serge E. Hallyn
maintainerPATCH 2/4 userns: let copy_ipcs handle setting ipc_ns->user_ns
In reply to Serge E. HallynTo do that, we have to pass in the task_struct of the task which will own the ipc_ns, so we can assign its user_ns.
--- include/linux/ipc_namespace.h | 8 +++++--- ipc/namespace.c | 12 +++++++----- kernel/nsproxy.c | 7 +------ 3 files changed, 13 insertions(+), 14 deletions(-)
include/linux/ipc_namespace.h +5 -3
@@ -92,7 +92,8 @@ static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; }#endif #if defined(CONFIG_IPC_NS ) -extern struct ipc_namespace *copy_ipcs (unsigned long flags, +extern struct ipc_namespace *copy_ipcs (struct task_struct *tsk, +unsigned long flags,struct ipc_namespace *ns);static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) {
@@ -103,8 +104,9 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)extern void put_ipc_ns (struct ipc_namespace *ns);#else -static inline struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns) +static inline struct ipc_namespace *copy_ipcs (struct task_struct *tsk, +unsigned long flags, +struct ipc_namespace *ns) {if (flags &CLONE_NEWIPC )return ERR_PTR (-EINVAL );
ipc/namespace.c +7 -5
@@ -15,7 +15,8 @@#include "util.h" -static struct ipc_namespace *create_ipc_ns (struct ipc_namespace *old_ns) +static struct ipc_namespace *create_ipc_ns (struct task_struct *tsk, +struct ipc_namespace *old_ns) {struct ipc_namespace *ns;int err;
@@ -44,17 +45,18 @@ static struct ipc_namespace *create_ipc_ns(struct ipc_namespace *old_ns)ipcns_notify (IPCNS_CREATED );register_ipcns_notifier (ns); - ns->user_ns = old_ns->user_ns; -get_user_ns (ns->user_ns); + ns->user_ns =get_user_ns (task_cred_xxx (tsk, user)->user_ns);return ns; } -struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) +struct ipc_namespace *copy_ipcs (struct task_struct *tsk, +unsigned long flags, +struct ipc_namespace *ns) {if (!(flags &CLONE_NEWIPC ))return get_ipc_ns (ns); -return create_ipc_ns (ns); +return create_ipc_ns (tsk, ns); }/*
kernel/nsproxy.c +1 -6
@@ -75,16 +75,11 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_uts; } - new_nsp->ipc_ns =copy_ipcs (flags, tsk->nsproxy->ipc_ns); + new_nsp->ipc_ns =copy_ipcs (tsk, flags, tsk->nsproxy->ipc_ns);if (IS_ERR (new_nsp->ipc_ns)) { err =PTR_ERR (new_nsp->ipc_ns); goto out_ipc; } -if (new_nsp->ipc_ns != tsk->nsproxy->ipc_ns) { -put_user_ns (new_nsp->ipc_ns->user_ns); - new_nsp->ipc_ns->user_ns =task_cred_xxx (tsk, user)->user_ns; -get_user_ns (new_nsp->ipc_ns->user_ns); - } new_nsp->pid_ns =copy_pid_ns (flags,task_active_pid_ns (tsk));if (IS_ERR (new_nsp->pid_ns)) {
Signature · 1 line
1.7.0.4
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 2/4] userns: let copy_ipcs handle setting ipc_ns->user_ns
Quoted 15 lines · Serge E. Hallyn
To do that, we have to pass in the
task_structof the task which will own theipc_ns, so we can assign itsuser_ns.Signed-off-by Serge E. Hallyn<[email protected]>--- include/linux/ipc_namespace.h | 8 +++++--- ipc/namespace.c | 12 +++++++----- kernel/nsproxy.c | 7 +------ 3 files changed, 13 insertions(+), 14 deletions(-)include/linux/ipc_namespace.h +0
-0
include/linux/ipc_namespace.h static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; } · line 97
Quoted 7 lines
include/linux/ipc_namespace.h +2
-1@@ -92,7 +92,8 @@ static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; }#endif #if defined(CONFIG_IPC_NS ) -extern struct ipc_namespace *copy_ipcs (unsigned long flags, +extern struct ipc_namespace *copy_ipcs (struct task_struct *tsk, +unsigned long flags,struct ipc_namespace *ns);
Same comment than patch 1/4
PATCH 2/4 userns: let copy_ipcs handle setting ipc_ns->user_ns
In reply to a message not in the archiveTo do that, we have to pass in the task_struct of the task which will own the ipc_ns, so we can assign its user_ns.
Changelog:
Feb 23: As per Oleg comment, just pass in tsk. To get the
ipc_ns from the nsproxy we need to include nsproxy.h
--- include/linux/ipc_namespace.h | 7 ++++--- ipc/namespace.c | 13 ++++++++----- kernel/nsproxy.c | 7 +------ 3 files changed, 13 insertions(+), 14 deletions(-)
include/linux/ipc_namespace.h +4 -3
@@ -5,6 +5,7 @@#include <linux/idr.h> #include <linux/rwsem.h> #include <linux/notifier.h> +#include <linux/nsproxy.h> /* * ipc namespace events
@@ -93,7 +94,7 @@ static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; }#if defined(CONFIG_IPC_NS )extern struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns); +struct task_struct *tsk);static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) {if (ns)
@@ -104,12 +105,12 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)extern void put_ipc_ns (struct ipc_namespace *ns);#else static inline struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns) +struct task_struct *tsk) {if (flags &CLONE_NEWIPC )return ERR_PTR (-EINVAL ); -return ns; +return tsk->nsproxy->ipc_ns; }static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns)
ipc/namespace.c +8 -5
@@ -15,7 +15,8 @@#include "util.h" -static struct ipc_namespace *create_ipc_ns (struct ipc_namespace *old_ns) +static struct ipc_namespace *create_ipc_ns (struct task_struct *tsk, +struct ipc_namespace *old_ns) {struct ipc_namespace *ns;int err;
@@ -44,17 +45,19 @@ static struct ipc_namespace *create_ipc_ns(struct ipc_namespace *old_ns)ipcns_notify (IPCNS_CREATED );register_ipcns_notifier (ns); - ns->user_ns = old_ns->user_ns; -get_user_ns (ns->user_ns); + ns->user_ns =get_user_ns (task_cred_xxx (tsk, user)->user_ns);return ns; } -struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) +struct ipc_namespace *copy_ipcs (unsigned long flags, +struct task_struct *tsk) { +struct ipc_namespace *ns = tsk->nsproxy->ipc_ns; +if (!(flags &CLONE_NEWIPC ))return get_ipc_ns (ns); -return create_ipc_ns (ns); +return create_ipc_ns (tsk, ns); }/*
kernel/nsproxy.c +1 -6
@@ -75,16 +75,11 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_uts; } - new_nsp->ipc_ns =copy_ipcs (flags, tsk->nsproxy->ipc_ns); + new_nsp->ipc_ns =copy_ipcs (flags, tsk);if (IS_ERR (new_nsp->ipc_ns)) { err =PTR_ERR (new_nsp->ipc_ns); goto out_ipc; } -if (new_nsp->ipc_ns != tsk->nsproxy->ipc_ns) { -put_user_ns (new_nsp->ipc_ns->user_ns); - new_nsp->ipc_ns->user_ns =task_cred_xxx (tsk, user)->user_ns; -get_user_ns (new_nsp->ipc_ns->user_ns); - } new_nsp->pid_ns =copy_pid_ns (flags,task_active_pid_ns (tsk));if (IS_ERR (new_nsp->pid_ns)) {
Signature · 1 line
1.7.0.4
Re: [PATCH 2/4] userns: let copy_ipcs handle setting ipc_ns->user_ns
In reply to Serge E. HallynQuoted 15 lines · Serge E. Hallyn
To do that, we have to pass in the
task_structof the task which will own theipc_ns, so we can assign itsuser_ns.Signed-off-by Serge E. Hallyn<[email protected]>--- include/linux/ipc_namespace.h | 8 +++++--- ipc/namespace.c | 12 +++++++----- kernel/nsproxy.c | 7 +------ 3 files changed, 13 insertions(+), 14 deletions(-)include/linux/ipc_namespace.h +0
-0
include/linux/ipc_namespace.h static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; } · line 97
Quoted 7 lines
include/linux/ipc_namespace.h +2
-1@@ -92,7 +92,8 @@ static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; }#endif #if defined(CONFIG_IPC_NS ) -extern struct ipc_namespace *copy_ipcs (unsigned long flags, +extern struct ipc_namespace *copy_ipcs (struct task_struct *tsk, +unsigned long flags,struct ipc_namespace *ns);
Same comment than patch 1/4
Serge E. Hallyn
maintainerPATCH 2/4 userns: let copy_ipcs handle setting ipc_ns->user_ns
In reply to Serge E. HallynTo do that, we have to pass in the task_struct of the task which will own the ipc_ns, so we can assign its user_ns.
Changelog:
Feb 23: As per Oleg comment, just pass in tsk. To get the
ipc_ns from the nsproxy we need to include nsproxy.h
--- include/linux/ipc_namespace.h | 7 ++++--- ipc/namespace.c | 13 ++++++++----- kernel/nsproxy.c | 7 +------ 3 files changed, 13 insertions(+), 14 deletions(-)
include/linux/ipc_namespace.h +4 -3
@@ -5,6 +5,7 @@#include <linux/idr.h> #include <linux/rwsem.h> #include <linux/notifier.h> +#include <linux/nsproxy.h> /* * ipc namespace events
@@ -93,7 +94,7 @@ static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; }#if defined(CONFIG_IPC_NS )extern struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns); +struct task_struct *tsk);static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns) {if (ns)
@@ -104,12 +105,12 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)extern void put_ipc_ns (struct ipc_namespace *ns);#else static inline struct ipc_namespace *copy_ipcs (unsigned long flags, -struct ipc_namespace *ns) +struct task_struct *tsk) {if (flags &CLONE_NEWIPC )return ERR_PTR (-EINVAL ); -return ns; +return tsk->nsproxy->ipc_ns; }static inline struct ipc_namespace *get_ipc_ns (struct ipc_namespace *ns)
ipc/namespace.c +8 -5
@@ -15,7 +15,8 @@#include "util.h" -static struct ipc_namespace *create_ipc_ns (struct ipc_namespace *old_ns) +static struct ipc_namespace *create_ipc_ns (struct task_struct *tsk, +struct ipc_namespace *old_ns) {struct ipc_namespace *ns;int err;
@@ -44,17 +45,19 @@ static struct ipc_namespace *create_ipc_ns(struct ipc_namespace *old_ns)ipcns_notify (IPCNS_CREATED );register_ipcns_notifier (ns); - ns->user_ns = old_ns->user_ns; -get_user_ns (ns->user_ns); + ns->user_ns =get_user_ns (task_cred_xxx (tsk, user)->user_ns);return ns; } -struct ipc_namespace *copy_ipcs (unsigned long flags,struct ipc_namespace *ns) +struct ipc_namespace *copy_ipcs (unsigned long flags, +struct task_struct *tsk) { +struct ipc_namespace *ns = tsk->nsproxy->ipc_ns; +if (!(flags &CLONE_NEWIPC ))return get_ipc_ns (ns); -return create_ipc_ns (ns); +return create_ipc_ns (tsk, ns); }/*
kernel/nsproxy.c +1 -6
@@ -75,16 +75,11 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_uts; } - new_nsp->ipc_ns =copy_ipcs (flags, tsk->nsproxy->ipc_ns); + new_nsp->ipc_ns =copy_ipcs (flags, tsk);if (IS_ERR (new_nsp->ipc_ns)) { err =PTR_ERR (new_nsp->ipc_ns); goto out_ipc; } -if (new_nsp->ipc_ns != tsk->nsproxy->ipc_ns) { -put_user_ns (new_nsp->ipc_ns->user_ns); - new_nsp->ipc_ns->user_ns =task_cred_xxx (tsk, user)->user_ns; -get_user_ns (new_nsp->ipc_ns->user_ns); - } new_nsp->pid_ns =copy_pid_ns (flags,task_active_pid_ns (tsk));if (IS_ERR (new_nsp->pid_ns)) {
Signature · 1 line
1.7.0.4
A message that is not in the archive (sent off-list or not yet received): [email protected]
Daniel Lezcano
Acked-byRe: [PATCH 2/4] userns: let copy_ipcs handle setting ipc_ns->user_ns
Quoted 9 lines · Serge E. Hallyn
To do that, we have to pass in the
task_structof the task which will own theipc_ns, so we can assign itsuser_ns.Changelog:
Feb 23: As per Oleg comment, just pass in tsk. To get the
ipc_nsfrom the nsproxy we need to includensproxy.hSigned-off-by Serge E. Hallyn<[email protected]>---
Re: [PATCH 2/4] userns: let copy_ipcs handle setting ipc_ns->user_ns
In reply to Serge E. HallynQuoted 9 lines · Serge E. Hallyn
To do that, we have to pass in the
task_structof the task which will own theipc_ns, so we can assign itsuser_ns.Changelog:
Feb 23: As per Oleg comment, just pass in tsk. To get the
ipc_nsfrom the nsproxy we need to includensproxy.hSigned-off-by Serge E. Hallyn<[email protected]>---
Serge E. Hallyn
maintainerPATCH 3/4 Add the required user_ns parameter to security_capable
In reply to Serge E. HallynFixes a compile failure.
--- drivers/pci/pci-sysfs.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/pci/pci-sysfs.c +1 -1
@@ -369,7 +369,7 @@ pci_read_config(struct file *filp, struct kobject *kobj,u8 *data = (u8 *) buf;/* Several chips lock up trying to read undefined config space */ -if (security_capable (filp->f_cred,CAP_SYS_ADMIN ) ==0 ) { +if (security_capable (&init_user_ns, filp->f_cred,CAP_SYS_ADMIN ) ==0 ) { size = dev->cfg_size; }else if (dev->hdr_type ==PCI_HEADER_TYPE_CARDBUS ) { size =128 ;
Signature · 1 line
1.7.0.4
Quoted 17 lines · Serge E. Hallyn
To do so we need to pass in the
task_structwho'll get the utsname, so we can get itsuser_ns.Signed-off-by Serge E. Hallyn<[email protected]>---
include/linux/utsname.h | 10 ++++++---- kernel/nsproxy.c | 7 +------ kernel/utsname.c | 12 +++++++----- 3 files changed, 14 insertions(+), 15 deletions(-)include/linux/utsname.h +0
-0
include/linux/utsname.h static inline void get_uts_ns(struct uts_namespace *ns) · line 57
Quoted 8 lines
include/linux/utsname.h +3
-2@@ -52,8 +52,9 @@ static inline void get_uts_ns(struct uts_namespace *ns)kref_get (&ns->kref); } -extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +extern struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns);
Why don't we pass 'user_ns' instead of 'tsk' ? that will look semantically clearer for the caller no ? (example below).
Quoted 20 lines
include/linux/utsname.h +3
-2extern void free_uts_ns (struct kref *kref);static inline void put_uts_ns (struct uts_namespace *ns)@@ -69,8 +70,9 @@ static inline void put_uts_ns(struct uts_namespace *ns) { } -static inline struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns) +static inline struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns) {if (flags&CLONE_NEWUTS )return ERR_PTR (-EINVAL );kernel/nsproxy.c +0
-0
kernel/nsproxy.c static struct nsproxy *create_new_namespaces(unsigned long flags, · line 76
Quoted 9 lines
kernel/nsproxy.c +1
-1@@ -69,16 +69,11 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_ns; } - new_nsp->uts_ns =copy_utsname (flags, tsk->nsproxy->uts_ns); + new_nsp->uts_ns =copy_utsname (tsk, flags, tsk->nsproxy->uts_ns);if (IS_ERR (new_nsp->uts_ns)) { err =PTR_ERR (new_nsp->uts_ns); goto out_uts; }
...
new_nsp->uts_ns = copy_utsname(flags, tsk->nsproxy->uts_ns, task_cred_xxx(tsk, user)->user_ns);
...
Quoted 52 lines
kernel/nsproxy.c +0
-5-if (new_nsp->uts_ns != tsk->nsproxy->uts_ns) { -put_user_ns (new_nsp->uts_ns->user_ns); - new_nsp->uts_ns->user_ns =task_cred_xxx (tsk, user)->user_ns; -get_user_ns (new_nsp->uts_ns->user_ns); - } new_nsp->ipc_ns =copy_ipcs (flags, tsk->nsproxy->ipc_ns);if (IS_ERR (new_nsp->ipc_ns)) {kernel/utsname.c +7
-5@@ -31,7 +31,8 @@ static struct uts_namespace *create_uts_ns(void)* @old_ns: namespace to clone * Return NULL on error (failure to kmalloc), new ns otherwise */ -static struct uts_namespace *clone_uts_ns (struct uts_namespace *old_ns) +static struct uts_namespace *clone_uts_ns (struct task_struct *tsk, +struct uts_namespace *old_ns) {struct uts_namespace *ns;@@ -41,8 +42,7 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)down_read (&uts_sem);memcpy (&ns->name,&old_ns->name,sizeof (ns->name)); - ns->user_ns = old_ns->user_ns; -get_user_ns (ns->user_ns); + ns->user_ns =get_user_ns (task_cred_xxx (tsk, user)->user_ns);up_read (&uts_sem);return ns; }@@ -53,7 +53,9 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)* utsname of this process won't be seen by parent, and vice * versa. */ -struct uts_namespace *copy_utsname (unsigned long flags,struct uts_namespace *old_ns) +struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *old_ns) {struct uts_namespace *new_ns;@@ -63,7 +65,7 @@ struct uts_namespace *copy_utsname(unsigned long flags, struct uts_namespace *olif (!(flags&CLONE_NEWUTS ))return old_ns; - new_ns =clone_uts_ns (old_ns); + new_ns =clone_uts_ns (tsk, old_ns);put_uts_ns (old_ns);return new_ns;
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 16 lines · Daniel Lezcano
include/linux/utsname.h static inline void get_uts_ns(struct uts_namespace *ns) · line 57
Quoted 8 lines · Serge E. Hallyn
To do so we need to pass in the
task_structwho'll get the utsname, so we can get itsuser_ns.include/linux/utsname.h +3
-2-extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +extern struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns);Why don't we pass '
user_ns' instead of 'tsk' ? that will look semantically clearer for the caller no ?
(example below).
...
Quoted 1 line
new_nsp->uts_ns=copy_utsname(flags, tsk->nsproxy->uts_ns, task_cred_xxx(tsk, user)->user_ns);
To me tsk looks more readable, I mean
new_nsp->uts_ns = copy_utsname(flags, tsk);
copy_utsname() can find both uts_ns and user_ns looking at task_strcut.
But this is cosmetic and up to you and Serge.
But. I think it makes sense to pass "tsk" argument to copy_pid_ns() as well. This way we can remove some CLONE_PIDNS code in copy_process(), and this looks like a nice cleanaup (even if minor) to me.
Oleg.
Quoted 16 lines · Daniel Lezcano
include/linux/utsname.h static inline void get_uts_ns(struct uts_namespace *ns) · line 57
Quoted 8 lines · Serge E. Hallyn
To do so we need to pass in the
task_structwho'll get the utsname, so we can get itsuser_ns.include/linux/utsname.h +3
-2-extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +extern struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns);Why don't we pass '
user_ns' instead of 'tsk' ? that will look semantically clearer for the caller no ?
(example below).
...
Quoted 1 line
new_nsp->uts_ns=copy_utsname(flags, tsk->nsproxy->uts_ns, task_cred_xxx(tsk, user)->user_ns);
To me tsk looks more readable, I mean
new_nsp->uts_ns = copy_utsname(flags, tsk);
copy_utsname() can find both uts_ns and user_ns looking at task_strcut.
But this is cosmetic and up to you and Serge.
But. I think it makes sense to pass "tsk" argument to copy_pid_ns() as well. This way we can remove some CLONE_PIDNS code in copy_process(), and this looks like a nice cleanaup (even if minor) to me.
Oleg.
Serge E. Hallyn
maintainerQuoted 17 lines · Oleg Nesterov
Quoted 16 lines · Daniel Lezcano
include/linux/utsname.h static inline void get_uts_ns(struct uts_namespace *ns) · line 57
Quoted 8 lines · Serge E. Hallyn
To do so we need to pass in the
task_structwho'll get the utsname, so we can get itsuser_ns.include/linux/utsname.h +3
-2-extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +extern struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns);Why don't we pass '
user_ns' instead of 'tsk' ? that will look semantically clearer for the caller no ?
(example below).
...
Quoted 7 lines
Quoted 1 line
new_nsp->uts_ns=copy_utsname(flags, tsk->nsproxy->uts_ns, task_cred_xxx(tsk, user)->user_ns);To me tsk looks more readable, I mean
new_nsp->uts_ns = copy_utsname(flags, tsk);
copy_utsname()can find bothuts_nsanduser_nslooking attask_strcut.
Uh, yeah. I should remove the 'ns' argument there shouldn't I.
Daniel, does that sway your opinion then?
thanks,
-serge
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 17 lines · Serge E. Hallyn
Quoted 16 lines · Oleg Nesterov
Quoted 15 lines · Daniel Lezcano
include/linux/utsname.h static inline void get_uts_ns(struct uts_namespace *ns) · line 57
Quoted 8 lines · Serge E. Hallyn
To do so we need to pass in the
task_structwho'll get the utsname, so we can get itsuser_ns.include/linux/utsname.h +3
-2-extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +extern struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns);Why don't we pass '
user_ns' instead of 'tsk' ? that will look semantically clearer for the caller no ?
(example below).
...
new_nsp->uts_ns=copy_utsname(flags, tsk->nsproxy->uts_ns, task_cred_xxx(tsk, user)->user_ns);
Quoted 8 lines
Quoted 5 lines
To me tsk looks more readable, I mean
new_nsp->uts_ns = copy_utsname(flags, tsk);
copy_utsname()can find bothuts_nsanduser_nslooking attask_strcut.Uh, yeah. I should remove the 'ns' argument there shouldn't I.
Daniel, does that sway your opinion then?
Well, I prefer to pass the needed parameters to a function. AFAICS, 'tsk' is not really needed but 'user_ns'.
But it is a detail, so if passing the tsk parameter in the other copy_* functions helps to cleanup, that will be consistent.
So I am fine with that.
Quoted 17 lines · Serge E. Hallyn
Quoted 16 lines · Oleg Nesterov
Quoted 15 lines · Daniel Lezcano
include/linux/utsname.h static inline void get_uts_ns(struct uts_namespace *ns) · line 57
Quoted 8 lines · Serge E. Hallyn
To do so we need to pass in the
task_structwho'll get the utsname, so we can get itsuser_ns.include/linux/utsname.h +3
-2-extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +extern struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns);Why don't we pass '
user_ns' instead of 'tsk' ? that will look semantically clearer for the caller no ?
(example below).
...
new_nsp->uts_ns=copy_utsname(flags, tsk->nsproxy->uts_ns, task_cred_xxx(tsk, user)->user_ns);
Quoted 8 lines
Quoted 5 lines
To me tsk looks more readable, I mean
new_nsp->uts_ns = copy_utsname(flags, tsk);
copy_utsname()can find bothuts_nsanduser_nslooking attask_strcut.Uh, yeah. I should remove the 'ns' argument there shouldn't I.
Daniel, does that sway your opinion then?
Well, I prefer to pass the needed parameters to a function. AFAICS, 'tsk' is not really needed but 'user_ns'. But it is a detail, so if passing the tsk parameter in the other copy_* functions helps to cleanup, that will be consistent. So I am fine with that.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 17 lines · Oleg Nesterov
Quoted 16 lines · Daniel Lezcano
include/linux/utsname.h static inline void get_uts_ns(struct uts_namespace *ns) · line 57
Quoted 8 lines · Serge E. Hallyn
To do so we need to pass in the
task_structwho'll get the utsname, so we can get itsuser_ns.include/linux/utsname.h +3
-2-extern struct uts_namespace *copy_utsname (unsigned long flags, -struct uts_namespace *ns); +extern struct uts_namespace *copy_utsname (struct task_struct *tsk, +unsigned long flags, +struct uts_namespace *ns);Why don't we pass '
user_ns' instead of 'tsk' ? that will look semantically clearer for the caller no ?
(example below).
...
Quoted 7 lines
Quoted 1 line
new_nsp->uts_ns=copy_utsname(flags, tsk->nsproxy->uts_ns, task_cred_xxx(tsk, user)->user_ns);To me tsk looks more readable, I mean
new_nsp->uts_ns = copy_utsname(flags, tsk);
copy_utsname()can find bothuts_nsanduser_nslooking attask_strcut.
Uh, yeah. I should remove the 'ns' argument there shouldn't I.
Daniel, does that sway your opinion then?
thanks,
-serge
Serge E. Hallyn
maintainerPATCH 4/4 userns: uts and ipc: fix checkpatch warning
In reply to Serge E. HallynAs pointed out by Andrew Morton (and checkpatch), init/version.c (and ipc/msgutil.c) should not have an extern declaration for init_user_ns. Instead, move those to ipc_namespace.h and utsname.h.
--- include/linux/ipc_namespace.h | 3 ++- include/linux/utsname.h | 1 + init/version.c | 1 - ipc/msgutil.c | 2 -- 4 files changed, 3 insertions(+), 4 deletions(-)
include/linux/ipc_namespace.h +2 -1
@@ -15,6 +15,8 @@#define IPCNS_CALLBACK_PRI 0 +struct user_namespace ; +extern struct user_namespace init_user_ns;struct ipc_ids {int in_use;
@@ -24,7 +26,6 @@ struct ipc_ids {struct idr ipcs_idr; }; -struct user_namespace ;struct ipc_namespace {atomic_t count;struct ipc_ids ids[3 ];
include/linux/utsname.h +1 -0
@@ -38,6 +38,7 @@ struct new_utsname {#include <linux/err.h> struct user_namespace ; +extern struct user_namespace init_user_ns;struct uts_namespace {struct kref kref;
init/version.c +0 -1
@@ -21,7 +21,6 @@ extern int version_string(LINUX_VERSION_CODE);int version_string (LINUX_VERSION_CODE );#endif -extern struct user_namespace init_user_ns;struct uts_namespace init_uts_ns = { .kref = { .refcount =ATOMIC_INIT (2 ),
ipc/msgutil.c +0 -2
@@ -20,8 +20,6 @@DEFINE_SPINLOCK (mq_lock); -extern struct user_namespace init_user_ns; -/* * The next 2 defines are here bc this is the only file * compiled when either CONFIG_SYSVIPC and CONFIG_POSIX_MQUEUE
Signature · 1 line
1.7.0.4
Serge E. Hallyn
maintainer[PATCH 5/4] Clean up capability.h and capability.c
In reply to Serge E. HallynConvert macros to functions to let type safety do its thing. Switch some functions from ints to more appropriate bool. Move all forward declarations together to top of the #ifdef __KERNEL__ section. Use kernel-doc format for comments.
Some macros couldn't be converted because they use functions from security.h which sometimes are extern and sometimes static inline, and we don't want to #include security.h in capability.h.
Also add a real current_user_ns function (and convert the existing macro to _current_user_ns() so we can use it in capability.h without #including cred.h.
--- include/linux/capability.h | 38 ++++++++++++++++++++++++++------------ include/linux/cred.h | 4 +++- kernel/capability.c | 20 ++++++++++++-------- kernel/cred.c | 5 +++++ 4 files changed, 46 insertions(+), 21 deletions(-)
include/linux/capability.h +26 -12
@@ -368,6 +368,17 @@ struct cpu_vfs_cap_data {#ifdef __KERNEL__ +struct dentry ; +struct user_namespace ; + +extern struct user_namespace init_user_ns; + +struct user_namespace *current_user_ns (void ); + +extern const kernel_cap_t __cap_empty_set; +extern const kernel_cap_t __cap_full_set; +extern const kernel_cap_t __cap_init_eff_set; +/* * Internal kernel functions only */
@@ -530,10 +541,6 @@ static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a, cap_intersect(permitted, __cap_nfsd_set)); } -extern const kernel_cap_t __cap_empty_set; -extern const kernel_cap_t __cap_full_set; -extern const kernel_cap_t __cap_init_eff_set; -/** * has_capability - Determine if a task has a superior capability available * @t: The task in question
@@ -560,18 +567,25 @@ extern const kernel_cap_t __cap_init_eff_set;* Note that this does not set PF_SUPERPRIV on the task. */ #define has_capability_noaudit (t, cap) \ - (security_real_capable_noaudit((t), &init_user_ns, (cap)) == 0) + (security_real_capable_noaudit((t), &init_user_ns, (cap)) == 0) -struct user_namespace ; -extern struct user_namespace init_user_ns; -extern int capable (int cap); -extern int ns_capable (struct user_namespace *ns,int cap); -extern int task_ns_capable (struct task_struct *t,int cap); +extern bool capable (int cap); +extern bool ns_capable (struct user_namespace *ns,int cap); +extern bool task_ns_capable (struct task_struct *t,int cap); -#define nsown_capable (cap) (ns_capable(current_user_ns(), (cap))) +/** +* nsown_capable - Check superior capability to one's own user_ns +* @cap: The capability in question +* +* Return true if the current task has the given superior capability +* targeted at its own user namespace. +*/ +static inline bool nsown_capable (int cap) +{ +return ns_capable (current_user_ns (), cap); +}/* audit system wants to get cap info from files as well */ -struct dentry ;extern int get_vfs_caps_from_disk (const struct dentry *dentry,struct cpu_vfs_cap_data *cpu_caps);#endif /* __KERNEL__ */
include/linux/cred.h +3 -1
@@ -354,9 +354,11 @@ static inline void put_cred(const struct cred *_cred)#define current_fsgid () (current_cred_xxx(fsgid))#define current_cap () (current_cred_xxx(cap_effective))#define current_user () (current_cred_xxx(user)) -#define current_user_ns () (current_cred_xxx(user)->user_ns) +#define _current_user_ns () (current_cred_xxx(user)->user_ns)#define current_security () (current_cred_xxx(security)) +extern struct user_namespace *current_user_ns (void ); +#define current_uid_gid (_uid, _gid) \ do { \ const struct cred *__cred; \
kernel/capability.c +12 -8
@@ -300,7 +300,7 @@ error:* This sets PF_SUPERPRIV on the task if the capability is available on the * assumption that it's about to be used. */ -int capable (int cap) +bool capable (int cap) {return ns_capable (&init_user_ns, cap); }
@@ -317,7 +317,7 @@ EXPORT_SYMBOL(capable);* This sets PF_SUPERPRIV on the task if the capability is available on the * assumption that it's about to be used. */ -int ns_capable (struct user_namespace *ns,int cap) +bool ns_capable (struct user_namespace *ns,int cap) {if (unlikely (!cap_valid (cap))) {printk (KERN_CRIT "capable() called with invalid cap=%u\n" , cap);
@@ -326,17 +326,21 @@ int ns_capable(struct user_namespace *ns, int cap)if (security_capable (ns,current_cred (), cap) ==0 ) { current->flags |=PF_SUPERPRIV ; -return 1 ; +return true; } -return 0 ; +return false; }EXPORT_SYMBOL (ns_capable); -/* -* does current have capability 'cap' to the user namespace of task -* 't'. Return true if it does, false otherwise. +/** +* task_ns_capable - Determine whether current task has a superior +* capability targeted at a specific task's user namespace. +* @t: The task whose user namespace is targeted. +* @cap: The capability in question. +* +* Return true if it does, false otherwise. */ -int task_ns_capable (struct task_struct *t,int cap) +bool task_ns_capable (struct task_struct *t,int cap) {return ns_capable (task_cred_xxx (t, user)->user_ns, cap); }
kernel/cred.c +5 -0
@@ -741,6 +741,11 @@ int set_create_files_as(struct cred *new, struct inode *inode) }EXPORT_SYMBOL (set_create_files_as); +struct user_namespace *current_user_ns (void ) +{ +return _current_user_ns (); +} +#ifdef CONFIG_DEBUG_CREDENTIALS bool creds_are_invalid (const struct cred *cred)
Signature · 1 line
1.7.0.4
A message that is not in the archive (sent off-list or not yet received): [email protected]
Daniel Lezcano
Acked-byRe: [PATCH 5/4] Clean up capability.h and capability.c
Quoted 9 lines · Serge E. Hallyn
Convert macros to functions to let type safety do its thing. Switch some functions from ints to more appropriate bool. Move all forward declarations together to top of the #ifdef
__KERNEL__section. Use kernel-doc format for comments.Some macros couldn't be converted because they use functions from
security.hwhich sometimes are extern and sometimes static inline, and we don't want to #includesecurity.hincapability.h.
Quoted 6 lines
Also add a real
current_user_nsfunction (and convert the existing macro to_current_user_ns()so we can use it incapability.hwithout #includingcred.h.Signed-off-by Serge E. Hallyn<[email protected]>---
Daniel Lezcano
Acked-byRe: [PATCH 5/4] Clean up capability.h and capability.c
In reply to Serge E. HallynQuoted 9 lines · Serge E. Hallyn
Convert macros to functions to let type safety do its thing. Switch some functions from ints to more appropriate bool. Move all forward declarations together to top of the #ifdef
__KERNEL__section. Use kernel-doc format for comments.Some macros couldn't be converted because they use functions from
security.hwhich sometimes are extern and sometimes static inline, and we don't want to #includesecurity.hincapability.h.
Quoted 6 lines
Also add a real
current_user_nsfunction (and convert the existing macro to_current_user_ns()so we can use it incapability.hwithout #includingcred.h.Signed-off-by Serge E. Hallyn<[email protected]>---