From 3d89622885e2fedb6f3f1e24ef3d37e289aad363 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 15 Mar 2013 01:45:51 -0700 Subject: [PATCH] --- yaml --- r: 361880 b: refs/heads/master c: 3151527ee007b73a0ebd296010f1c0454a919c7d h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/namespace.c | 24 ++++++++++++++++++++++++ trunk/include/linux/fs_struct.h | 2 ++ trunk/kernel/user_namespace.c | 9 +++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 6d13babb21b7..89cfec78aaef 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: eddc0a3abff273842a94784d2d022bbc36dc9015 +refs/heads/master: 3151527ee007b73a0ebd296010f1c0454a919c7d diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 50ca17d3cb45..a3035223d421 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -2732,6 +2732,30 @@ bool our_mnt(struct vfsmount *mnt) return check_mnt(real_mount(mnt)); } +bool current_chrooted(void) +{ + /* Does the current process have a non-standard root */ + struct path ns_root; + struct path fs_root; + bool chrooted; + + /* Find the namespace root */ + ns_root.mnt = ¤t->nsproxy->mnt_ns->root->mnt; + ns_root.dentry = ns_root.mnt->mnt_root; + path_get(&ns_root); + while (d_mountpoint(ns_root.dentry) && follow_down_one(&ns_root)) + ; + + get_fs_root(current->fs, &fs_root); + + chrooted = !path_equal(&fs_root, &ns_root); + + path_put(&fs_root); + path_put(&ns_root); + + return chrooted; +} + static void *mntns_get(struct task_struct *task) { struct mnt_namespace *ns = NULL; diff --git a/trunk/include/linux/fs_struct.h b/trunk/include/linux/fs_struct.h index 729eded4b24f..2b93a9a5a1e6 100644 --- a/trunk/include/linux/fs_struct.h +++ b/trunk/include/linux/fs_struct.h @@ -50,4 +50,6 @@ static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, spin_unlock(&fs->lock); } +extern bool current_chrooted(void); + #endif /* _LINUX_FS_STRUCT_H */ diff --git a/trunk/kernel/user_namespace.c b/trunk/kernel/user_namespace.c index b14f4d342043..0f1e42884577 100644 --- a/trunk/kernel/user_namespace.c +++ b/trunk/kernel/user_namespace.c @@ -61,6 +61,15 @@ int create_user_ns(struct cred *new) kgid_t group = new->egid; int ret; + /* + * Verify that we can not violate the policy of which files + * may be accessed that is specified by the root directory, + * by verifing that the root directory is at the root of the + * mount namespace which allows all files to be accessed. + */ + if (current_chrooted()) + return -EPERM; + /* The creator needs a mapping in the parent user namespace * or else we won't be able to reasonably tell userspace who * created a user_namespace.