aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c106
1 files changed, 50 insertions, 56 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index f30b11e2240e..411728c0c8bb 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -112,9 +112,13 @@ struct vfsmount *alloc_vfsmnt(const char *name)
112 int err; 112 int err;
113 113
114 err = mnt_alloc_id(mnt); 114 err = mnt_alloc_id(mnt);
115 if (err) { 115 if (err)
116 kmem_cache_free(mnt_cache, mnt); 116 goto out_free_cache;
117 return NULL; 117
118 if (name) {
119 mnt->mnt_devname = kstrdup(name, GFP_KERNEL);
120 if (!mnt->mnt_devname)
121 goto out_free_id;
118 } 122 }
119 123
120 atomic_set(&mnt->mnt_count, 1); 124 atomic_set(&mnt->mnt_count, 1);
@@ -127,16 +131,14 @@ struct vfsmount *alloc_vfsmnt(const char *name)
127 INIT_LIST_HEAD(&mnt->mnt_slave_list); 131 INIT_LIST_HEAD(&mnt->mnt_slave_list);
128 INIT_LIST_HEAD(&mnt->mnt_slave); 132 INIT_LIST_HEAD(&mnt->mnt_slave);
129 atomic_set(&mnt->__mnt_writers, 0); 133 atomic_set(&mnt->__mnt_writers, 0);
130 if (name) {
131 int size = strlen(name) + 1;
132 char *newname = kmalloc(size, GFP_KERNEL);
133 if (newname) {
134 memcpy(newname, name, size);
135 mnt->mnt_devname = newname;
136 }
137 }
138 } 134 }
139 return mnt; 135 return mnt;
136
137out_free_id:
138 mnt_free_id(mnt);
139out_free_cache:
140 kmem_cache_free(mnt_cache, mnt);
141 return NULL;
140} 142}
141 143
142/* 144/*
@@ -1128,27 +1130,27 @@ static int do_umount(struct vfsmount *mnt, int flags)
1128 1130
1129asmlinkage long sys_umount(char __user * name, int flags) 1131asmlinkage long sys_umount(char __user * name, int flags)
1130{ 1132{
1131 struct nameidata nd; 1133 struct path path;
1132 int retval; 1134 int retval;
1133 1135
1134 retval = __user_walk(name, LOOKUP_FOLLOW, &nd); 1136 retval = user_path(name, &path);
1135 if (retval) 1137 if (retval)
1136 goto out; 1138 goto out;
1137 retval = -EINVAL; 1139 retval = -EINVAL;
1138 if (nd.path.dentry != nd.path.mnt->mnt_root) 1140 if (path.dentry != path.mnt->mnt_root)
1139 goto dput_and_out; 1141 goto dput_and_out;
1140 if (!check_mnt(nd.path.mnt)) 1142 if (!check_mnt(path.mnt))
1141 goto dput_and_out; 1143 goto dput_and_out;
1142 1144
1143 retval = -EPERM; 1145 retval = -EPERM;
1144 if (!capable(CAP_SYS_ADMIN)) 1146 if (!capable(CAP_SYS_ADMIN))
1145 goto dput_and_out; 1147 goto dput_and_out;
1146 1148
1147 retval = do_umount(nd.path.mnt, flags); 1149 retval = do_umount(path.mnt, flags);
1148dput_and_out: 1150dput_and_out:
1149 /* we mustn't call path_put() as that would clear mnt_expiry_mark */ 1151 /* we mustn't call path_put() as that would clear mnt_expiry_mark */
1150 dput(nd.path.dentry); 1152 dput(path.dentry);
1151 mntput_no_expire(nd.path.mnt); 1153 mntput_no_expire(path.mnt);
1152out: 1154out:
1153 return retval; 1155 return retval;
1154} 1156}
@@ -1972,7 +1974,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
1972 struct fs_struct *fs) 1974 struct fs_struct *fs)
1973{ 1975{
1974 struct mnt_namespace *new_ns; 1976 struct mnt_namespace *new_ns;
1975 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; 1977 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
1976 struct vfsmount *p, *q; 1978 struct vfsmount *p, *q;
1977 1979
1978 new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL); 1980 new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
@@ -2015,10 +2017,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2015 pwdmnt = p; 2017 pwdmnt = p;
2016 fs->pwd.mnt = mntget(q); 2018 fs->pwd.mnt = mntget(q);
2017 } 2019 }
2018 if (p == fs->altroot.mnt) {
2019 altrootmnt = p;
2020 fs->altroot.mnt = mntget(q);
2021 }
2022 } 2020 }
2023 p = next_mnt(p, mnt_ns->root); 2021 p = next_mnt(p, mnt_ns->root);
2024 q = next_mnt(q, new_ns->root); 2022 q = next_mnt(q, new_ns->root);
@@ -2029,8 +2027,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2029 mntput(rootmnt); 2027 mntput(rootmnt);
2030 if (pwdmnt) 2028 if (pwdmnt)
2031 mntput(pwdmnt); 2029 mntput(pwdmnt);
2032 if (altrootmnt)
2033 mntput(altrootmnt);
2034 2030
2035 return new_ns; 2031 return new_ns;
2036} 2032}
@@ -2183,28 +2179,26 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
2183 const char __user * put_old) 2179 const char __user * put_old)
2184{ 2180{
2185 struct vfsmount *tmp; 2181 struct vfsmount *tmp;
2186 struct nameidata new_nd, old_nd; 2182 struct path new, old, parent_path, root_parent, root;
2187 struct path parent_path, root_parent, root;
2188 int error; 2183 int error;
2189 2184
2190 if (!capable(CAP_SYS_ADMIN)) 2185 if (!capable(CAP_SYS_ADMIN))
2191 return -EPERM; 2186 return -EPERM;
2192 2187
2193 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, 2188 error = user_path_dir(new_root, &new);
2194 &new_nd);
2195 if (error) 2189 if (error)
2196 goto out0; 2190 goto out0;
2197 error = -EINVAL; 2191 error = -EINVAL;
2198 if (!check_mnt(new_nd.path.mnt)) 2192 if (!check_mnt(new.mnt))
2199 goto out1; 2193 goto out1;
2200 2194
2201 error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd); 2195 error = user_path_dir(put_old, &old);
2202 if (error) 2196 if (error)
2203 goto out1; 2197 goto out1;
2204 2198
2205 error = security_sb_pivotroot(&old_nd.path, &new_nd.path); 2199 error = security_sb_pivotroot(&old, &new);
2206 if (error) { 2200 if (error) {
2207 path_put(&old_nd.path); 2201 path_put(&old);
2208 goto out1; 2202 goto out1;
2209 } 2203 }
2210 2204
@@ -2213,69 +2207,69 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
2213 path_get(&current->fs->root); 2207 path_get(&current->fs->root);
2214 read_unlock(&current->fs->lock); 2208 read_unlock(&current->fs->lock);
2215 down_write(&namespace_sem); 2209 down_write(&namespace_sem);
2216 mutex_lock(&old_nd.path.dentry->d_inode->i_mutex); 2210 mutex_lock(&old.dentry->d_inode->i_mutex);
2217 error = -EINVAL; 2211 error = -EINVAL;
2218 if (IS_MNT_SHARED(old_nd.path.mnt) || 2212 if (IS_MNT_SHARED(old.mnt) ||
2219 IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) || 2213 IS_MNT_SHARED(new.mnt->mnt_parent) ||
2220 IS_MNT_SHARED(root.mnt->mnt_parent)) 2214 IS_MNT_SHARED(root.mnt->mnt_parent))
2221 goto out2; 2215 goto out2;
2222 if (!check_mnt(root.mnt)) 2216 if (!check_mnt(root.mnt))
2223 goto out2; 2217 goto out2;
2224 error = -ENOENT; 2218 error = -ENOENT;
2225 if (IS_DEADDIR(new_nd.path.dentry->d_inode)) 2219 if (IS_DEADDIR(new.dentry->d_inode))
2226 goto out2; 2220 goto out2;
2227 if (d_unhashed(new_nd.path.dentry) && !IS_ROOT(new_nd.path.dentry)) 2221 if (d_unhashed(new.dentry) && !IS_ROOT(new.dentry))
2228 goto out2; 2222 goto out2;
2229 if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry)) 2223 if (d_unhashed(old.dentry) && !IS_ROOT(old.dentry))
2230 goto out2; 2224 goto out2;
2231 error = -EBUSY; 2225 error = -EBUSY;
2232 if (new_nd.path.mnt == root.mnt || 2226 if (new.mnt == root.mnt ||
2233 old_nd.path.mnt == root.mnt) 2227 old.mnt == root.mnt)
2234 goto out2; /* loop, on the same file system */ 2228 goto out2; /* loop, on the same file system */
2235 error = -EINVAL; 2229 error = -EINVAL;
2236 if (root.mnt->mnt_root != root.dentry) 2230 if (root.mnt->mnt_root != root.dentry)
2237 goto out2; /* not a mountpoint */ 2231 goto out2; /* not a mountpoint */
2238 if (root.mnt->mnt_parent == root.mnt) 2232 if (root.mnt->mnt_parent == root.mnt)
2239 goto out2; /* not attached */ 2233 goto out2; /* not attached */
2240 if (new_nd.path.mnt->mnt_root != new_nd.path.dentry) 2234 if (new.mnt->mnt_root != new.dentry)
2241 goto out2; /* not a mountpoint */ 2235 goto out2; /* not a mountpoint */
2242 if (new_nd.path.mnt->mnt_parent == new_nd.path.mnt) 2236 if (new.mnt->mnt_parent == new.mnt)
2243 goto out2; /* not attached */ 2237 goto out2; /* not attached */
2244 /* make sure we can reach put_old from new_root */ 2238 /* make sure we can reach put_old from new_root */
2245 tmp = old_nd.path.mnt; 2239 tmp = old.mnt;
2246 spin_lock(&vfsmount_lock); 2240 spin_lock(&vfsmount_lock);
2247 if (tmp != new_nd.path.mnt) { 2241 if (tmp != new.mnt) {
2248 for (;;) { 2242 for (;;) {
2249 if (tmp->mnt_parent == tmp) 2243 if (tmp->mnt_parent == tmp)
2250 goto out3; /* already mounted on put_old */ 2244 goto out3; /* already mounted on put_old */
2251 if (tmp->mnt_parent == new_nd.path.mnt) 2245 if (tmp->mnt_parent == new.mnt)
2252 break; 2246 break;
2253 tmp = tmp->mnt_parent; 2247 tmp = tmp->mnt_parent;
2254 } 2248 }
2255 if (!is_subdir(tmp->mnt_mountpoint, new_nd.path.dentry)) 2249 if (!is_subdir(tmp->mnt_mountpoint, new.dentry))
2256 goto out3; 2250 goto out3;
2257 } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) 2251 } else if (!is_subdir(old.dentry, new.dentry))
2258 goto out3; 2252 goto out3;
2259 detach_mnt(new_nd.path.mnt, &parent_path); 2253 detach_mnt(new.mnt, &parent_path);
2260 detach_mnt(root.mnt, &root_parent); 2254 detach_mnt(root.mnt, &root_parent);
2261 /* mount old root on put_old */ 2255 /* mount old root on put_old */
2262 attach_mnt(root.mnt, &old_nd.path); 2256 attach_mnt(root.mnt, &old);
2263 /* mount new_root on / */ 2257 /* mount new_root on / */
2264 attach_mnt(new_nd.path.mnt, &root_parent); 2258 attach_mnt(new.mnt, &root_parent);
2265 touch_mnt_namespace(current->nsproxy->mnt_ns); 2259 touch_mnt_namespace(current->nsproxy->mnt_ns);
2266 spin_unlock(&vfsmount_lock); 2260 spin_unlock(&vfsmount_lock);
2267 chroot_fs_refs(&root, &new_nd.path); 2261 chroot_fs_refs(&root, &new);
2268 security_sb_post_pivotroot(&root, &new_nd.path); 2262 security_sb_post_pivotroot(&root, &new);
2269 error = 0; 2263 error = 0;
2270 path_put(&root_parent); 2264 path_put(&root_parent);
2271 path_put(&parent_path); 2265 path_put(&parent_path);
2272out2: 2266out2:
2273 mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); 2267 mutex_unlock(&old.dentry->d_inode->i_mutex);
2274 up_write(&namespace_sem); 2268 up_write(&namespace_sem);
2275 path_put(&root); 2269 path_put(&root);
2276 path_put(&old_nd.path); 2270 path_put(&old);
2277out1: 2271out1:
2278 path_put(&new_nd.path); 2272 path_put(&new);
2279out0: 2273out0:
2280 return error; 2274 return error;
2281out3: 2275out3: