>From nobody Mon Sep 17 00:00:00 2001 From: Serge E. Hallyn <serue@xxxxxxxxxx> Date: Thu, 5 Apr 2007 14:02:09 -0400 Subject: [PATCH 3/6] user ns: add an inode user_ns pointer Add a user namespace pointer to each inode. One user namespace is said to own each inode. Each filesystem can fill these in for itself. By default it is NULL, meaning that user namespace checks will be skipped. At first most filesystems will presumably assign a user namespace to the fs superblock info, and assign that to each inode on the fs. If this seems limiting based on this description, see the long-ish development roadmap to see why it is really the best way to go, and in no way limiting. Signed-off-by: Serge E. Hallyn <serue@xxxxxxxxxx> --- fs/inode.c | 2 ++ include/linux/fs.h | 3 +++ include/linux/user_namespace.h | 25 +++++++++++++++++++++++++ kernel/user_namespace.c | 18 ++++++++++++++++++ 4 files changed, 48 insertions(+), 0 deletions(-) c76b1d886c98c9661e794fa7f58dbaa4f4613864 diff --git a/fs/inode.c b/fs/inode.c index 42cb8e5..2eab0f1 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -23,6 +23,7 @@ #include <linux/cdev.h> #include <linux/bootmem.h> #include <linux/inotify.h> #include <linux/mount.h> +#include <linux/user_namespace.h> /* * This is needed for the following functions: @@ -116,6 +117,7 @@ static struct inode *alloc_inode(struct struct address_space * const mapping = &inode->i_data; inode->i_sb = sb; + inode->i_userns = NULL; inode->i_blkbits = sb->s_blocksize_bits; inode->i_flags = 0; atomic_set(&inode->i_count, 1); diff --git a/include/linux/fs.h b/include/linux/fs.h index 2e46ad7..d021658 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -527,6 +527,8 @@ #else #define i_size_ordered_init(inode) do { } while (0) #endif +struct user_namespace; + struct inode { struct hlist_node i_hash; struct list_head i_list; @@ -536,6 +538,7 @@ struct inode { atomic_t i_count; unsigned int i_nlink; uid_t i_uid; + struct user_namespace *i_userns; gid_t i_gid; dev_t i_rdev; unsigned long i_version; diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index 9044456..3b5e040 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -4,6 +4,7 @@ #define _LINUX_USER_NAMESPACE_H #include <linux/kref.h> #include <linux/nsproxy.h> #include <linux/sched.h> +#include <linux/err.h> #define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 8) #define UIDHASH_SZ (1 << UIDHASH_BITS) @@ -35,6 +36,25 @@ static inline void put_user_ns(struct us kref_put(&ns->kref, free_user_ns); } +struct user_namespace *task_user_ns(struct task_struct *tsk); +struct user_namespace *inode_user_ns(struct inode *inode); +/* + * task_inode_same_userns: + * If inode->i_userns is NULL, the fs does not support user namespaces, so any + * user namespace may access it as though it owned it. Otherwise, any user + * not in the owning user namespace will be treated as 'nobody'. + * + * once we implement a user namespace keychain, we will want to augment this + * to also check for the existance of (inode->i_userns, inode->i_uid) as a key + * in the keychain for the user running tsk. + */ +static inline int +task_inode_same_userns(struct task_struct *tsk, struct inode *inode) +{ + struct user_namespace *ino_userns = inode_user_ns(inode); + + return (!ino_userns || task_user_ns(tsk)== ino_userns); +} #else static inline struct user_namespace *get_user_ns(struct user_namespace *ns) @@ -55,6 +75,11 @@ static inline void put_user_ns(struct us { } +static inline int +task_inode_same_userns(struct task_struct *tsk, struct inode *inode) +{ + return 1; +} #endif #endif /* _LINUX_USER_H */ diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 89a27e8..f487361 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -84,4 +84,22 @@ void free_user_ns(struct kref *kref) kfree(ns); } +struct user_namespace *task_user_ns(struct task_struct *tsk) +{ + return tsk->nsproxy->user_ns; +} + +struct user_namespace *get_task_user_ns(struct task_struct *tsk) +{ + return get_user_ns(task_user_ns(tsk)); +} + +/* should this just go into fs.h? */ +#include <linux/fs.h> +struct user_namespace *inode_user_ns(struct inode *inode) +{ + return inode->i_userns; +} + + #endif /* CONFIG_USER_NS */ -- 1.3.2 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers