aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c109
1 files changed, 51 insertions, 58 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 4f6f7635b59c..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/*
@@ -309,10 +311,9 @@ static void handle_write_count_underflow(struct vfsmount *mnt)
309 */ 311 */
310 if ((atomic_read(&mnt->__mnt_writers) < 0) && 312 if ((atomic_read(&mnt->__mnt_writers) < 0) &&
311 !(mnt->mnt_flags & MNT_IMBALANCED_WRITE_COUNT)) { 313 !(mnt->mnt_flags & MNT_IMBALANCED_WRITE_COUNT)) {
312 printk(KERN_DEBUG "leak detected on mount(%p) writers " 314 WARN(1, KERN_DEBUG "leak detected on mount(%p) writers "
313 "count: %d\n", 315 "count: %d\n",
314 mnt, atomic_read(&mnt->__mnt_writers)); 316 mnt, atomic_read(&mnt->__mnt_writers));
315 WARN_ON(1);
316 /* use the flag to keep the dmesg spam down */ 317 /* use the flag to keep the dmesg spam down */
317 mnt->mnt_flags |= MNT_IMBALANCED_WRITE_COUNT; 318 mnt->mnt_flags |= MNT_IMBALANCED_WRITE_COUNT;
318 } 319 }
@@ -1129,27 +1130,27 @@ static int do_umount(struct vfsmount *mnt, int flags)
1129 1130
1130asmlinkage long sys_umount(char __user * name, int flags) 1131asmlinkage long sys_umount(char __user * name, int flags)
1131{ 1132{
1132 struct nameidata nd; 1133 struct path path;
1133 int retval; 1134 int retval;
1134 1135
1135 retval = __user_walk(name, LOOKUP_FOLLOW, &nd); 1136 retval = user_path(name, &path);
1136 if (retval) 1137 if (retval)
1137 goto out; 1138 goto out;
1138 retval = -EINVAL; 1139 retval = -EINVAL;
1139 if (nd.path.dentry != nd.path.mnt->mnt_root) 1140 if (path.dentry != path.mnt->mnt_root)
1140 goto dput_and_out; 1141 goto dput_and_out;
1141 if (!check_mnt(nd.path.mnt)) 1142 if (!check_mnt(path.mnt))
1142 goto dput_and_out; 1143 goto dput_and_out;
1143 1144
1144 retval = -EPERM; 1145 retval = -EPERM;
1145 if (!capable(CAP_SYS_ADMIN)) 1146 if (!capable(CAP_SYS_ADMIN))
1146 goto dput_and_out; 1147 goto dput_and_out;
1147 1148
1148 retval = do_umount(nd.path.mnt, flags); 1149 retval = do_umount(path.mnt, flags);
1149dput_and_out: 1150dput_and_out:
1150 /* 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 */
1151 dput(nd.path.dentry); 1152 dput(path.dentry);
1152 mntput_no_expire(nd.path.mnt); 1153 mntput_no_expire(path.mnt);
1153out: 1154out:
1154 return retval; 1155 return retval;
1155} 1156}
@@ -1973,7 +1974,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
1973 struct fs_struct *fs) 1974 struct fs_struct *fs)
1974{ 1975{
1975 struct mnt_namespace *new_ns; 1976 struct mnt_namespace *new_ns;
1976 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; 1977 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
1977 struct vfsmount *p, *q; 1978 struct vfsmount *p, *q;
1978 1979
1979 new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL); 1980 new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
@@ -2016,10 +2017,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2016 pwdmnt = p; 2017 pwdmnt = p;
2017 fs->pwd.mnt = mntget(q); 2018 fs->pwd.mnt = mntget(q);
2018 } 2019 }
2019 if (p == fs->altroot.mnt) {
2020 altrootmnt = p;
2021 fs->altroot.mnt = mntget(q);
2022 }
2023 } 2020 }
2024 p = next_mnt(p, mnt_ns->root); 2021 p = next_mnt(p, mnt_ns->root);
2025 q = next_mnt(q, new_ns->root); 2022 q = next_mnt(q, new_ns->root);
@@ -2030,8 +2027,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2030 mntput(rootmnt); 2027 mntput(rootmnt);
2031 if (pwdmnt) 2028 if (pwdmnt)
2032 mntput(pwdmnt); 2029 mntput(pwdmnt);
2033 if (altrootmnt)
2034 mntput(altrootmnt);
2035 2030
2036 return new_ns; 2031 return new_ns;
2037} 2032}
@@ -2184,28 +2179,26 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
2184 const char __user * put_old) 2179 const char __user * put_old)
2185{ 2180{
2186 struct vfsmount *tmp; 2181 struct vfsmount *tmp;
2187 struct nameidata new_nd, old_nd; 2182 struct path new, old, parent_path, root_parent, root;
2188 struct path parent_path, root_parent, root;
2189 int error; 2183 int error;
2190 2184
2191 if (!capable(CAP_SYS_ADMIN)) 2185 if (!capable(CAP_SYS_ADMIN))
2192 return -EPERM; 2186 return -EPERM;
2193 2187
2194 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, 2188 error = user_path_dir(new_root, &new);
2195 &new_nd);
2196 if (error) 2189 if (error)
2197 goto out0; 2190 goto out0;
2198 error = -EINVAL; 2191 error = -EINVAL;
2199 if (!check_mnt(new_nd.path.mnt)) 2192 if (!check_mnt(new.mnt))
2200 goto out1; 2193 goto out1;
2201 2194
2202 error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd); 2195 error = user_path_dir(put_old, &old);
2203 if (error) 2196 if (error)
2204 goto out1; 2197 goto out1;
2205 2198
2206 error = security_sb_pivotroot(&old_nd.path, &new_nd.path); 2199 error = security_sb_pivotroot(&old, &new);
2207 if (error) { 2200 if (error) {
2208 path_put(&old_nd.path); 2201 path_put(&old);
2209 goto out1; 2202 goto out1;
2210 } 2203 }
2211 2204
@@ -2214,69 +2207,69 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
2214 path_get(&current->fs->root); 2207 path_get(&current->fs->root);
2215 read_unlock(&current->fs->lock); 2208 read_unlock(&current->fs->lock);
2216 down_write(&namespace_sem); 2209 down_write(&namespace_sem);
2217 mutex_lock(&old_nd.path.dentry->d_inode->i_mutex); 2210 mutex_lock(&old.dentry->d_inode->i_mutex);
2218 error = -EINVAL; 2211 error = -EINVAL;
2219 if (IS_MNT_SHARED(old_nd.path.mnt) || 2212 if (IS_MNT_SHARED(old.mnt) ||
2220 IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) || 2213 IS_MNT_SHARED(new.mnt->mnt_parent) ||
2221 IS_MNT_SHARED(root.mnt->mnt_parent)) 2214 IS_MNT_SHARED(root.mnt->mnt_parent))
2222 goto out2; 2215 goto out2;
2223 if (!check_mnt(root.mnt)) 2216 if (!check_mnt(root.mnt))
2224 goto out2; 2217 goto out2;
2225 error = -ENOENT; 2218 error = -ENOENT;
2226 if (IS_DEADDIR(new_nd.path.dentry->d_inode)) 2219 if (IS_DEADDIR(new.dentry->d_inode))
2227 goto out2; 2220 goto out2;
2228 if (d_unhashed(new_nd.path.dentry) && !IS_ROOT(new_nd.path.dentry)) 2221 if (d_unhashed(new.dentry) && !IS_ROOT(new.dentry))
2229 goto out2; 2222 goto out2;
2230 if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry)) 2223 if (d_unhashed(old.dentry) && !IS_ROOT(old.dentry))
2231 goto out2; 2224 goto out2;
2232 error = -EBUSY; 2225 error = -EBUSY;
2233 if (new_nd.path.mnt == root.mnt || 2226 if (new.mnt == root.mnt ||
2234 old_nd.path.mnt == root.mnt) 2227 old.mnt == root.mnt)
2235 goto out2; /* loop, on the same file system */ 2228 goto out2; /* loop, on the same file system */
2236 error = -EINVAL; 2229 error = -EINVAL;
2237 if (root.mnt->mnt_root != root.dentry) 2230 if (root.mnt->mnt_root != root.dentry)
2238 goto out2; /* not a mountpoint */ 2231 goto out2; /* not a mountpoint */
2239 if (root.mnt->mnt_parent == root.mnt) 2232 if (root.mnt->mnt_parent == root.mnt)
2240 goto out2; /* not attached */ 2233 goto out2; /* not attached */
2241 if (new_nd.path.mnt->mnt_root != new_nd.path.dentry) 2234 if (new.mnt->mnt_root != new.dentry)
2242 goto out2; /* not a mountpoint */ 2235 goto out2; /* not a mountpoint */
2243 if (new_nd.path.mnt->mnt_parent == new_nd.path.mnt) 2236 if (new.mnt->mnt_parent == new.mnt)
2244 goto out2; /* not attached */ 2237 goto out2; /* not attached */
2245 /* make sure we can reach put_old from new_root */ 2238 /* make sure we can reach put_old from new_root */
2246 tmp = old_nd.path.mnt; 2239 tmp = old.mnt;
2247 spin_lock(&vfsmount_lock); 2240 spin_lock(&vfsmount_lock);
2248 if (tmp != new_nd.path.mnt) { 2241 if (tmp != new.mnt) {
2249 for (;;) { 2242 for (;;) {
2250 if (tmp->mnt_parent == tmp) 2243 if (tmp->mnt_parent == tmp)
2251 goto out3; /* already mounted on put_old */ 2244 goto out3; /* already mounted on put_old */
2252 if (tmp->mnt_parent == new_nd.path.mnt) 2245 if (tmp->mnt_parent == new.mnt)
2253 break; 2246 break;
2254 tmp = tmp->mnt_parent; 2247 tmp = tmp->mnt_parent;
2255 } 2248 }
2256 if (!is_subdir(tmp->mnt_mountpoint, new_nd.path.dentry)) 2249 if (!is_subdir(tmp->mnt_mountpoint, new.dentry))
2257 goto out3; 2250 goto out3;
2258 } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) 2251 } else if (!is_subdir(old.dentry, new.dentry))
2259 goto out3; 2252 goto out3;
2260 detach_mnt(new_nd.path.mnt, &parent_path); 2253 detach_mnt(new.mnt, &parent_path);
2261 detach_mnt(root.mnt, &root_parent); 2254 detach_mnt(root.mnt, &root_parent);
2262 /* mount old root on put_old */ 2255 /* mount old root on put_old */
2263 attach_mnt(root.mnt, &old_nd.path); 2256 attach_mnt(root.mnt, &old);
2264 /* mount new_root on / */ 2257 /* mount new_root on / */
2265 attach_mnt(new_nd.path.mnt, &root_parent); 2258 attach_mnt(new.mnt, &root_parent);
2266 touch_mnt_namespace(current->nsproxy->mnt_ns); 2259 touch_mnt_namespace(current->nsproxy->mnt_ns);
2267 spin_unlock(&vfsmount_lock); 2260 spin_unlock(&vfsmount_lock);
2268 chroot_fs_refs(&root, &new_nd.path); 2261 chroot_fs_refs(&root, &new);
2269 security_sb_post_pivotroot(&root, &new_nd.path); 2262 security_sb_post_pivotroot(&root, &new);
2270 error = 0; 2263 error = 0;
2271 path_put(&root_parent); 2264 path_put(&root_parent);
2272 path_put(&parent_path); 2265 path_put(&parent_path);
2273out2: 2266out2:
2274 mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); 2267 mutex_unlock(&old.dentry->d_inode->i_mutex);
2275 up_write(&namespace_sem); 2268 up_write(&namespace_sem);
2276 path_put(&root); 2269 path_put(&root);
2277 path_put(&old_nd.path); 2270 path_put(&old);
2278out1: 2271out1:
2279 path_put(&new_nd.path); 2272 path_put(&new);
2280out0: 2273out0:
2281 return error; 2274 return error;
2282out3: 2275out3: