diff options
-rw-r--r-- | fs/namespace.c | 24 | ||||
-rw-r--r-- | include/linux/fs_struct.h | 2 | ||||
-rw-r--r-- | kernel/user_namespace.c | 9 |
3 files changed, 35 insertions, 0 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 50ca17d3cb45..a3035223d421 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -2732,6 +2732,30 @@ bool our_mnt(struct vfsmount *mnt) | |||
2732 | return check_mnt(real_mount(mnt)); | 2732 | return check_mnt(real_mount(mnt)); |
2733 | } | 2733 | } |
2734 | 2734 | ||
2735 | bool current_chrooted(void) | ||
2736 | { | ||
2737 | /* Does the current process have a non-standard root */ | ||
2738 | struct path ns_root; | ||
2739 | struct path fs_root; | ||
2740 | bool chrooted; | ||
2741 | |||
2742 | /* Find the namespace root */ | ||
2743 | ns_root.mnt = ¤t->nsproxy->mnt_ns->root->mnt; | ||
2744 | ns_root.dentry = ns_root.mnt->mnt_root; | ||
2745 | path_get(&ns_root); | ||
2746 | while (d_mountpoint(ns_root.dentry) && follow_down_one(&ns_root)) | ||
2747 | ; | ||
2748 | |||
2749 | get_fs_root(current->fs, &fs_root); | ||
2750 | |||
2751 | chrooted = !path_equal(&fs_root, &ns_root); | ||
2752 | |||
2753 | path_put(&fs_root); | ||
2754 | path_put(&ns_root); | ||
2755 | |||
2756 | return chrooted; | ||
2757 | } | ||
2758 | |||
2735 | static void *mntns_get(struct task_struct *task) | 2759 | static void *mntns_get(struct task_struct *task) |
2736 | { | 2760 | { |
2737 | struct mnt_namespace *ns = NULL; | 2761 | struct mnt_namespace *ns = NULL; |
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index 729eded4b24f..2b93a9a5a1e6 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h | |||
@@ -50,4 +50,6 @@ static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, | |||
50 | spin_unlock(&fs->lock); | 50 | spin_unlock(&fs->lock); |
51 | } | 51 | } |
52 | 52 | ||
53 | extern bool current_chrooted(void); | ||
54 | |||
53 | #endif /* _LINUX_FS_STRUCT_H */ | 55 | #endif /* _LINUX_FS_STRUCT_H */ |
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index b14f4d342043..0f1e42884577 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c | |||
@@ -61,6 +61,15 @@ int create_user_ns(struct cred *new) | |||
61 | kgid_t group = new->egid; | 61 | kgid_t group = new->egid; |
62 | int ret; | 62 | int ret; |
63 | 63 | ||
64 | /* | ||
65 | * Verify that we can not violate the policy of which files | ||
66 | * may be accessed that is specified by the root directory, | ||
67 | * by verifing that the root directory is at the root of the | ||
68 | * mount namespace which allows all files to be accessed. | ||
69 | */ | ||
70 | if (current_chrooted()) | ||
71 | return -EPERM; | ||
72 | |||
64 | /* The creator needs a mapping in the parent user namespace | 73 | /* The creator needs a mapping in the parent user namespace |
65 | * or else we won't be able to reasonably tell userspace who | 74 | * or else we won't be able to reasonably tell userspace who |
66 | * created a user_namespace. | 75 | * created a user_namespace. |