aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c354
1 files changed, 118 insertions, 236 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 01e67dddcc3d..a7b0a0b80128 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -31,7 +31,6 @@
31#include <linux/file.h> 31#include <linux/file.h>
32#include <linux/fcntl.h> 32#include <linux/fcntl.h>
33#include <linux/device_cgroup.h> 33#include <linux/device_cgroup.h>
34#include <asm/namei.h>
35#include <asm/uaccess.h> 34#include <asm/uaccess.h>
36 35
37#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) 36#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
@@ -185,6 +184,8 @@ int generic_permission(struct inode *inode, int mask,
185{ 184{
186 umode_t mode = inode->i_mode; 185 umode_t mode = inode->i_mode;
187 186
187 mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
188
188 if (current->fsuid == inode->i_uid) 189 if (current->fsuid == inode->i_uid)
189 mode >>= 6; 190 mode >>= 6;
190 else { 191 else {
@@ -203,7 +204,7 @@ int generic_permission(struct inode *inode, int mask,
203 /* 204 /*
204 * If the DACs are ok we don't need any capability check. 205 * If the DACs are ok we don't need any capability check.
205 */ 206 */
206 if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)) 207 if ((mask & ~mode) == 0)
207 return 0; 208 return 0;
208 209
209 check_capabilities: 210 check_capabilities:
@@ -226,13 +227,9 @@ int generic_permission(struct inode *inode, int mask,
226 return -EACCES; 227 return -EACCES;
227} 228}
228 229
229int permission(struct inode *inode, int mask, struct nameidata *nd) 230int inode_permission(struct inode *inode, int mask)
230{ 231{
231 int retval, submask; 232 int retval;
232 struct vfsmount *mnt = NULL;
233
234 if (nd)
235 mnt = nd->path.mnt;
236 233
237 if (mask & MAY_WRITE) { 234 if (mask & MAY_WRITE) {
238 umode_t mode = inode->i_mode; 235 umode_t mode = inode->i_mode;
@@ -251,19 +248,9 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
251 return -EACCES; 248 return -EACCES;
252 } 249 }
253 250
254 if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
255 /*
256 * MAY_EXEC on regular files is denied if the fs is mounted
257 * with the "noexec" flag.
258 */
259 if (mnt && (mnt->mnt_flags & MNT_NOEXEC))
260 return -EACCES;
261 }
262
263 /* Ordinary permission routines do not understand MAY_APPEND. */ 251 /* Ordinary permission routines do not understand MAY_APPEND. */
264 submask = mask & ~MAY_APPEND;
265 if (inode->i_op && inode->i_op->permission) { 252 if (inode->i_op && inode->i_op->permission) {
266 retval = inode->i_op->permission(inode, submask, nd); 253 retval = inode->i_op->permission(inode, mask);
267 if (!retval) { 254 if (!retval) {
268 /* 255 /*
269 * Exec permission on a regular file is denied if none 256 * Exec permission on a regular file is denied if none
@@ -277,7 +264,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
277 return -EACCES; 264 return -EACCES;
278 } 265 }
279 } else { 266 } else {
280 retval = generic_permission(inode, submask, NULL); 267 retval = generic_permission(inode, mask, NULL);
281 } 268 }
282 if (retval) 269 if (retval)
283 return retval; 270 return retval;
@@ -286,7 +273,8 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
286 if (retval) 273 if (retval)
287 return retval; 274 return retval;
288 275
289 return security_inode_permission(inode, mask, nd); 276 return security_inode_permission(inode,
277 mask & (MAY_READ|MAY_WRITE|MAY_EXEC));
290} 278}
291 279
292/** 280/**
@@ -301,7 +289,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
301 */ 289 */
302int vfs_permission(struct nameidata *nd, int mask) 290int vfs_permission(struct nameidata *nd, int mask)
303{ 291{
304 return permission(nd->path.dentry->d_inode, mask, nd); 292 return inode_permission(nd->path.dentry->d_inode, mask);
305} 293}
306 294
307/** 295/**
@@ -318,7 +306,7 @@ int vfs_permission(struct nameidata *nd, int mask)
318 */ 306 */
319int file_permission(struct file *file, int mask) 307int file_permission(struct file *file, int mask)
320{ 308{
321 return permission(file->f_path.dentry->d_inode, mask, NULL); 309 return inode_permission(file->f_path.dentry->d_inode, mask);
322} 310}
323 311
324/* 312/*
@@ -459,8 +447,7 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name,
459 * short-cut DAC fails, then call permission() to do more 447 * short-cut DAC fails, then call permission() to do more
460 * complete permission check. 448 * complete permission check.
461 */ 449 */
462static int exec_permission_lite(struct inode *inode, 450static int exec_permission_lite(struct inode *inode)
463 struct nameidata *nd)
464{ 451{
465 umode_t mode = inode->i_mode; 452 umode_t mode = inode->i_mode;
466 453
@@ -486,7 +473,7 @@ static int exec_permission_lite(struct inode *inode,
486 473
487 return -EACCES; 474 return -EACCES;
488ok: 475ok:
489 return security_inode_permission(inode, MAY_EXEC, nd); 476 return security_inode_permission(inode, MAY_EXEC);
490} 477}
491 478
492/* 479/*
@@ -519,7 +506,14 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
519 */ 506 */
520 result = d_lookup(parent, name); 507 result = d_lookup(parent, name);
521 if (!result) { 508 if (!result) {
522 struct dentry * dentry = d_alloc(parent, name); 509 struct dentry *dentry;
510
511 /* Don't create child dentry for a dead directory. */
512 result = ERR_PTR(-ENOENT);
513 if (IS_DEADDIR(dir))
514 goto out_unlock;
515
516 dentry = d_alloc(parent, name);
523 result = ERR_PTR(-ENOMEM); 517 result = ERR_PTR(-ENOMEM);
524 if (dentry) { 518 if (dentry) {
525 result = dir->i_op->lookup(dir, dentry, nd); 519 result = dir->i_op->lookup(dir, dentry, nd);
@@ -528,6 +522,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
528 else 522 else
529 result = dentry; 523 result = dentry;
530 } 524 }
525out_unlock:
531 mutex_unlock(&dir->i_mutex); 526 mutex_unlock(&dir->i_mutex);
532 return result; 527 return result;
533 } 528 }
@@ -545,27 +540,16 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
545 return result; 540 return result;
546} 541}
547 542
548static int __emul_lookup_dentry(const char *, struct nameidata *);
549
550/* SMP-safe */ 543/* SMP-safe */
551static __always_inline int 544static __always_inline void
552walk_init_root(const char *name, struct nameidata *nd) 545walk_init_root(const char *name, struct nameidata *nd)
553{ 546{
554 struct fs_struct *fs = current->fs; 547 struct fs_struct *fs = current->fs;
555 548
556 read_lock(&fs->lock); 549 read_lock(&fs->lock);
557 if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
558 nd->path = fs->altroot;
559 path_get(&fs->altroot);
560 read_unlock(&fs->lock);
561 if (__emul_lookup_dentry(name,nd))
562 return 0;
563 read_lock(&fs->lock);
564 }
565 nd->path = fs->root; 550 nd->path = fs->root;
566 path_get(&fs->root); 551 path_get(&fs->root);
567 read_unlock(&fs->lock); 552 read_unlock(&fs->lock);
568 return 1;
569} 553}
570 554
571/* 555/*
@@ -606,12 +590,9 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
606 590
607 if (*link == '/') { 591 if (*link == '/') {
608 path_put(&nd->path); 592 path_put(&nd->path);
609 if (!walk_init_root(link, nd)) 593 walk_init_root(link, nd);
610 /* weird __emul_prefix() stuff did it */
611 goto out;
612 } 594 }
613 res = link_path_walk(link, nd); 595 res = link_path_walk(link, nd);
614out:
615 if (nd->depth || res || nd->last_type!=LAST_NORM) 596 if (nd->depth || res || nd->last_type!=LAST_NORM)
616 return res; 597 return res;
617 /* 598 /*
@@ -889,7 +870,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
889 unsigned int c; 870 unsigned int c;
890 871
891 nd->flags |= LOOKUP_CONTINUE; 872 nd->flags |= LOOKUP_CONTINUE;
892 err = exec_permission_lite(inode, nd); 873 err = exec_permission_lite(inode);
893 if (err == -EAGAIN) 874 if (err == -EAGAIN)
894 err = vfs_permission(nd, MAY_EXEC); 875 err = vfs_permission(nd, MAY_EXEC);
895 if (err) 876 if (err)
@@ -1060,67 +1041,6 @@ static int path_walk(const char *name, struct nameidata *nd)
1060 return link_path_walk(name, nd); 1041 return link_path_walk(name, nd);
1061} 1042}
1062 1043
1063/*
1064 * SMP-safe: Returns 1 and nd will have valid dentry and mnt, if
1065 * everything is done. Returns 0 and drops input nd, if lookup failed;
1066 */
1067static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
1068{
1069 if (path_walk(name, nd))
1070 return 0; /* something went wrong... */
1071
1072 if (!nd->path.dentry->d_inode ||
1073 S_ISDIR(nd->path.dentry->d_inode->i_mode)) {
1074 struct path old_path = nd->path;
1075 struct qstr last = nd->last;
1076 int last_type = nd->last_type;
1077 struct fs_struct *fs = current->fs;
1078
1079 /*
1080 * NAME was not found in alternate root or it's a directory.
1081 * Try to find it in the normal root:
1082 */
1083 nd->last_type = LAST_ROOT;
1084 read_lock(&fs->lock);
1085 nd->path = fs->root;
1086 path_get(&fs->root);
1087 read_unlock(&fs->lock);
1088 if (path_walk(name, nd) == 0) {
1089 if (nd->path.dentry->d_inode) {
1090 path_put(&old_path);
1091 return 1;
1092 }
1093 path_put(&nd->path);
1094 }
1095 nd->path = old_path;
1096 nd->last = last;
1097 nd->last_type = last_type;
1098 }
1099 return 1;
1100}
1101
1102void set_fs_altroot(void)
1103{
1104 char *emul = __emul_prefix();
1105 struct nameidata nd;
1106 struct path path = {}, old_path;
1107 int err;
1108 struct fs_struct *fs = current->fs;
1109
1110 if (!emul)
1111 goto set_it;
1112 err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
1113 if (!err)
1114 path = nd.path;
1115set_it:
1116 write_lock(&fs->lock);
1117 old_path = fs->altroot;
1118 fs->altroot = path;
1119 write_unlock(&fs->lock);
1120 if (old_path.dentry)
1121 path_put(&old_path);
1122}
1123
1124/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ 1044/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
1125static int do_path_lookup(int dfd, const char *name, 1045static int do_path_lookup(int dfd, const char *name,
1126 unsigned int flags, struct nameidata *nd) 1046 unsigned int flags, struct nameidata *nd)
@@ -1136,14 +1056,6 @@ static int do_path_lookup(int dfd, const char *name,
1136 1056
1137 if (*name=='/') { 1057 if (*name=='/') {
1138 read_lock(&fs->lock); 1058 read_lock(&fs->lock);
1139 if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
1140 nd->path = fs->altroot;
1141 path_get(&fs->altroot);
1142 read_unlock(&fs->lock);
1143 if (__emul_lookup_dentry(name,nd))
1144 goto out; /* found in altroot */
1145 read_lock(&fs->lock);
1146 }
1147 nd->path = fs->root; 1059 nd->path = fs->root;
1148 path_get(&fs->root); 1060 path_get(&fs->root);
1149 read_unlock(&fs->lock); 1061 read_unlock(&fs->lock);
@@ -1177,7 +1089,6 @@ static int do_path_lookup(int dfd, const char *name,
1177 } 1089 }
1178 1090
1179 retval = path_walk(name, nd); 1091 retval = path_walk(name, nd);
1180out:
1181 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && 1092 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
1182 nd->path.dentry->d_inode)) 1093 nd->path.dentry->d_inode))
1183 audit_inode(name, nd->path.dentry); 1094 audit_inode(name, nd->path.dentry);
@@ -1282,19 +1193,6 @@ static int path_lookup_create(int dfd, const char *name,
1282 nd, open_flags, create_mode); 1193 nd, open_flags, create_mode);
1283} 1194}
1284 1195
1285int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags,
1286 struct nameidata *nd, int open_flags)
1287{
1288 char *tmp = getname(name);
1289 int err = PTR_ERR(tmp);
1290
1291 if (!IS_ERR(tmp)) {
1292 err = __path_lookup_intent_open(AT_FDCWD, tmp, lookup_flags, nd, open_flags, 0);
1293 putname(tmp);
1294 }
1295 return err;
1296}
1297
1298static struct dentry *__lookup_hash(struct qstr *name, 1196static struct dentry *__lookup_hash(struct qstr *name,
1299 struct dentry *base, struct nameidata *nd) 1197 struct dentry *base, struct nameidata *nd)
1300{ 1198{
@@ -1317,7 +1215,14 @@ static struct dentry *__lookup_hash(struct qstr *name,
1317 1215
1318 dentry = cached_lookup(base, name, nd); 1216 dentry = cached_lookup(base, name, nd);
1319 if (!dentry) { 1217 if (!dentry) {
1320 struct dentry *new = d_alloc(base, name); 1218 struct dentry *new;
1219
1220 /* Don't create child dentry for a dead directory. */
1221 dentry = ERR_PTR(-ENOENT);
1222 if (IS_DEADDIR(inode))
1223 goto out;
1224
1225 new = d_alloc(base, name);
1321 dentry = ERR_PTR(-ENOMEM); 1226 dentry = ERR_PTR(-ENOMEM);
1322 if (!new) 1227 if (!new)
1323 goto out; 1228 goto out;
@@ -1340,7 +1245,7 @@ static struct dentry *lookup_hash(struct nameidata *nd)
1340{ 1245{
1341 int err; 1246 int err;
1342 1247
1343 err = permission(nd->path.dentry->d_inode, MAY_EXEC, nd); 1248 err = inode_permission(nd->path.dentry->d_inode, MAY_EXEC);
1344 if (err) 1249 if (err)
1345 return ERR_PTR(err); 1250 return ERR_PTR(err);
1346 return __lookup_hash(&nd->last, nd->path.dentry, nd); 1251 return __lookup_hash(&nd->last, nd->path.dentry, nd);
@@ -1388,7 +1293,7 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
1388 if (err) 1293 if (err)
1389 return ERR_PTR(err); 1294 return ERR_PTR(err);
1390 1295
1391 err = permission(base->d_inode, MAY_EXEC, NULL); 1296 err = inode_permission(base->d_inode, MAY_EXEC);
1392 if (err) 1297 if (err)
1393 return ERR_PTR(err); 1298 return ERR_PTR(err);
1394 return __lookup_hash(&this, base, NULL); 1299 return __lookup_hash(&this, base, NULL);
@@ -1416,22 +1321,40 @@ struct dentry *lookup_one_noperm(const char *name, struct dentry *base)
1416 return __lookup_hash(&this, base, NULL); 1321 return __lookup_hash(&this, base, NULL);
1417} 1322}
1418 1323
1419int __user_walk_fd(int dfd, const char __user *name, unsigned flags, 1324int user_path_at(int dfd, const char __user *name, unsigned flags,
1420 struct nameidata *nd) 1325 struct path *path)
1421{ 1326{
1327 struct nameidata nd;
1422 char *tmp = getname(name); 1328 char *tmp = getname(name);
1423 int err = PTR_ERR(tmp); 1329 int err = PTR_ERR(tmp);
1424
1425 if (!IS_ERR(tmp)) { 1330 if (!IS_ERR(tmp)) {
1426 err = do_path_lookup(dfd, tmp, flags, nd); 1331
1332 BUG_ON(flags & LOOKUP_PARENT);
1333
1334 err = do_path_lookup(dfd, tmp, flags, &nd);
1427 putname(tmp); 1335 putname(tmp);
1336 if (!err)
1337 *path = nd.path;
1428 } 1338 }
1429 return err; 1339 return err;
1430} 1340}
1431 1341
1432int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd) 1342static int user_path_parent(int dfd, const char __user *path,
1343 struct nameidata *nd, char **name)
1433{ 1344{
1434 return __user_walk_fd(AT_FDCWD, name, flags, nd); 1345 char *s = getname(path);
1346 int error;
1347
1348 if (IS_ERR(s))
1349 return PTR_ERR(s);
1350
1351 error = do_path_lookup(dfd, s, LOOKUP_PARENT, nd);
1352 if (error)
1353 putname(s);
1354 else
1355 *name = s;
1356
1357 return error;
1435} 1358}
1436 1359
1437/* 1360/*
@@ -1478,7 +1401,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
1478 BUG_ON(victim->d_parent->d_inode != dir); 1401 BUG_ON(victim->d_parent->d_inode != dir);
1479 audit_inode_child(victim->d_name.name, victim, dir); 1402 audit_inode_child(victim->d_name.name, victim, dir);
1480 1403
1481 error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); 1404 error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
1482 if (error) 1405 if (error)
1483 return error; 1406 return error;
1484 if (IS_APPEND(dir)) 1407 if (IS_APPEND(dir))
@@ -1515,7 +1438,7 @@ static inline int may_create(struct inode *dir, struct dentry *child,
1515 return -EEXIST; 1438 return -EEXIST;
1516 if (IS_DEADDIR(dir)) 1439 if (IS_DEADDIR(dir))
1517 return -ENOENT; 1440 return -ENOENT;
1518 return permission(dir,MAY_WRITE | MAY_EXEC, nd); 1441 return inode_permission(dir, MAY_WRITE | MAY_EXEC);
1519} 1442}
1520 1443
1521/* 1444/*
@@ -1755,7 +1678,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
1755 int will_write; 1678 int will_write;
1756 int flag = open_to_namei_flags(open_flag); 1679 int flag = open_to_namei_flags(open_flag);
1757 1680
1758 acc_mode = ACC_MODE(flag); 1681 acc_mode = MAY_OPEN | ACC_MODE(flag);
1759 1682
1760 /* O_TRUNC implies we need access checks for write permissions */ 1683 /* O_TRUNC implies we need access checks for write permissions */
1761 if (flag & O_TRUNC) 1684 if (flag & O_TRUNC)
@@ -2071,20 +1994,18 @@ static int may_mknod(mode_t mode)
2071asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, 1994asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
2072 unsigned dev) 1995 unsigned dev)
2073{ 1996{
2074 int error = 0; 1997 int error;
2075 char * tmp; 1998 char *tmp;
2076 struct dentry * dentry; 1999 struct dentry *dentry;
2077 struct nameidata nd; 2000 struct nameidata nd;
2078 2001
2079 if (S_ISDIR(mode)) 2002 if (S_ISDIR(mode))
2080 return -EPERM; 2003 return -EPERM;
2081 tmp = getname(filename);
2082 if (IS_ERR(tmp))
2083 return PTR_ERR(tmp);
2084 2004
2085 error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd); 2005 error = user_path_parent(dfd, filename, &nd, &tmp);
2086 if (error) 2006 if (error)
2087 goto out; 2007 return error;
2008
2088 dentry = lookup_create(&nd, 0); 2009 dentry = lookup_create(&nd, 0);
2089 if (IS_ERR(dentry)) { 2010 if (IS_ERR(dentry)) {
2090 error = PTR_ERR(dentry); 2011 error = PTR_ERR(dentry);
@@ -2116,7 +2037,6 @@ out_dput:
2116out_unlock: 2037out_unlock:
2117 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2038 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2118 path_put(&nd.path); 2039 path_put(&nd.path);
2119out:
2120 putname(tmp); 2040 putname(tmp);
2121 2041
2122 return error; 2042 return error;
@@ -2156,14 +2076,10 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
2156 struct dentry *dentry; 2076 struct dentry *dentry;
2157 struct nameidata nd; 2077 struct nameidata nd;
2158 2078
2159 tmp = getname(pathname); 2079 error = user_path_parent(dfd, pathname, &nd, &tmp);
2160 error = PTR_ERR(tmp); 2080 if (error)
2161 if (IS_ERR(tmp))
2162 goto out_err; 2081 goto out_err;
2163 2082
2164 error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
2165 if (error)
2166 goto out;
2167 dentry = lookup_create(&nd, 1); 2083 dentry = lookup_create(&nd, 1);
2168 error = PTR_ERR(dentry); 2084 error = PTR_ERR(dentry);
2169 if (IS_ERR(dentry)) 2085 if (IS_ERR(dentry))
@@ -2181,7 +2097,6 @@ out_dput:
2181out_unlock: 2097out_unlock:
2182 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2098 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2183 path_put(&nd.path); 2099 path_put(&nd.path);
2184out:
2185 putname(tmp); 2100 putname(tmp);
2186out_err: 2101out_err:
2187 return error; 2102 return error;
@@ -2259,13 +2174,9 @@ static long do_rmdir(int dfd, const char __user *pathname)
2259 struct dentry *dentry; 2174 struct dentry *dentry;
2260 struct nameidata nd; 2175 struct nameidata nd;
2261 2176
2262 name = getname(pathname); 2177 error = user_path_parent(dfd, pathname, &nd, &name);
2263 if(IS_ERR(name))
2264 return PTR_ERR(name);
2265
2266 error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
2267 if (error) 2178 if (error)
2268 goto exit; 2179 return error;
2269 2180
2270 switch(nd.last_type) { 2181 switch(nd.last_type) {
2271 case LAST_DOTDOT: 2182 case LAST_DOTDOT:
@@ -2294,7 +2205,6 @@ exit2:
2294 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2205 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2295exit1: 2206exit1:
2296 path_put(&nd.path); 2207 path_put(&nd.path);
2297exit:
2298 putname(name); 2208 putname(name);
2299 return error; 2209 return error;
2300} 2210}
@@ -2343,19 +2253,16 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
2343 */ 2253 */
2344static long do_unlinkat(int dfd, const char __user *pathname) 2254static long do_unlinkat(int dfd, const char __user *pathname)
2345{ 2255{
2346 int error = 0; 2256 int error;
2347 char * name; 2257 char *name;
2348 struct dentry *dentry; 2258 struct dentry *dentry;
2349 struct nameidata nd; 2259 struct nameidata nd;
2350 struct inode *inode = NULL; 2260 struct inode *inode = NULL;
2351 2261
2352 name = getname(pathname); 2262 error = user_path_parent(dfd, pathname, &nd, &name);
2353 if(IS_ERR(name))
2354 return PTR_ERR(name);
2355
2356 error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
2357 if (error) 2263 if (error)
2358 goto exit; 2264 return error;
2265
2359 error = -EISDIR; 2266 error = -EISDIR;
2360 if (nd.last_type != LAST_NORM) 2267 if (nd.last_type != LAST_NORM)
2361 goto exit1; 2268 goto exit1;
@@ -2382,7 +2289,6 @@ static long do_unlinkat(int dfd, const char __user *pathname)
2382 iput(inode); /* truncate the inode here */ 2289 iput(inode); /* truncate the inode here */
2383exit1: 2290exit1:
2384 path_put(&nd.path); 2291 path_put(&nd.path);
2385exit:
2386 putname(name); 2292 putname(name);
2387 return error; 2293 return error;
2388 2294
@@ -2408,7 +2314,7 @@ asmlinkage long sys_unlink(const char __user *pathname)
2408 return do_unlinkat(AT_FDCWD, pathname); 2314 return do_unlinkat(AT_FDCWD, pathname);
2409} 2315}
2410 2316
2411int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode) 2317int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
2412{ 2318{
2413 int error = may_create(dir, dentry, NULL); 2319 int error = may_create(dir, dentry, NULL);
2414 2320
@@ -2432,23 +2338,20 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, i
2432asmlinkage long sys_symlinkat(const char __user *oldname, 2338asmlinkage long sys_symlinkat(const char __user *oldname,
2433 int newdfd, const char __user *newname) 2339 int newdfd, const char __user *newname)
2434{ 2340{
2435 int error = 0; 2341 int error;
2436 char * from; 2342 char *from;
2437 char * to; 2343 char *to;
2438 struct dentry *dentry; 2344 struct dentry *dentry;
2439 struct nameidata nd; 2345 struct nameidata nd;
2440 2346
2441 from = getname(oldname); 2347 from = getname(oldname);
2442 if(IS_ERR(from)) 2348 if (IS_ERR(from))
2443 return PTR_ERR(from); 2349 return PTR_ERR(from);
2444 to = getname(newname);
2445 error = PTR_ERR(to);
2446 if (IS_ERR(to))
2447 goto out_putname;
2448 2350
2449 error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); 2351 error = user_path_parent(newdfd, newname, &nd, &to);
2450 if (error) 2352 if (error)
2451 goto out; 2353 goto out_putname;
2354
2452 dentry = lookup_create(&nd, 0); 2355 dentry = lookup_create(&nd, 0);
2453 error = PTR_ERR(dentry); 2356 error = PTR_ERR(dentry);
2454 if (IS_ERR(dentry)) 2357 if (IS_ERR(dentry))
@@ -2457,14 +2360,13 @@ asmlinkage long sys_symlinkat(const char __user *oldname,
2457 error = mnt_want_write(nd.path.mnt); 2360 error = mnt_want_write(nd.path.mnt);
2458 if (error) 2361 if (error)
2459 goto out_dput; 2362 goto out_dput;
2460 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); 2363 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
2461 mnt_drop_write(nd.path.mnt); 2364 mnt_drop_write(nd.path.mnt);
2462out_dput: 2365out_dput:
2463 dput(dentry); 2366 dput(dentry);
2464out_unlock: 2367out_unlock:
2465 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2368 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2466 path_put(&nd.path); 2369 path_put(&nd.path);
2467out:
2468 putname(to); 2370 putname(to);
2469out_putname: 2371out_putname:
2470 putname(from); 2372 putname(from);
@@ -2498,19 +2400,19 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
2498 return -EPERM; 2400 return -EPERM;
2499 if (!dir->i_op || !dir->i_op->link) 2401 if (!dir->i_op || !dir->i_op->link)
2500 return -EPERM; 2402 return -EPERM;
2501 if (S_ISDIR(old_dentry->d_inode->i_mode)) 2403 if (S_ISDIR(inode->i_mode))
2502 return -EPERM; 2404 return -EPERM;
2503 2405
2504 error = security_inode_link(old_dentry, dir, new_dentry); 2406 error = security_inode_link(old_dentry, dir, new_dentry);
2505 if (error) 2407 if (error)
2506 return error; 2408 return error;
2507 2409
2508 mutex_lock(&old_dentry->d_inode->i_mutex); 2410 mutex_lock(&inode->i_mutex);
2509 DQUOT_INIT(dir); 2411 DQUOT_INIT(dir);
2510 error = dir->i_op->link(old_dentry, dir, new_dentry); 2412 error = dir->i_op->link(old_dentry, dir, new_dentry);
2511 mutex_unlock(&old_dentry->d_inode->i_mutex); 2413 mutex_unlock(&inode->i_mutex);
2512 if (!error) 2414 if (!error)
2513 fsnotify_link(dir, old_dentry->d_inode, new_dentry); 2415 fsnotify_link(dir, inode, new_dentry);
2514 return error; 2416 return error;
2515} 2417}
2516 2418
@@ -2528,27 +2430,25 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2528 int flags) 2430 int flags)
2529{ 2431{
2530 struct dentry *new_dentry; 2432 struct dentry *new_dentry;
2531 struct nameidata nd, old_nd; 2433 struct nameidata nd;
2434 struct path old_path;
2532 int error; 2435 int error;
2533 char * to; 2436 char *to;
2534 2437
2535 if ((flags & ~AT_SYMLINK_FOLLOW) != 0) 2438 if ((flags & ~AT_SYMLINK_FOLLOW) != 0)
2536 return -EINVAL; 2439 return -EINVAL;
2537 2440
2538 to = getname(newname); 2441 error = user_path_at(olddfd, oldname,
2539 if (IS_ERR(to)) 2442 flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0,
2540 return PTR_ERR(to); 2443 &old_path);
2541
2542 error = __user_walk_fd(olddfd, oldname,
2543 flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0,
2544 &old_nd);
2545 if (error) 2444 if (error)
2546 goto exit; 2445 return error;
2547 error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); 2446
2447 error = user_path_parent(newdfd, newname, &nd, &to);
2548 if (error) 2448 if (error)
2549 goto out; 2449 goto out;
2550 error = -EXDEV; 2450 error = -EXDEV;
2551 if (old_nd.path.mnt != nd.path.mnt) 2451 if (old_path.mnt != nd.path.mnt)
2552 goto out_release; 2452 goto out_release;
2553 new_dentry = lookup_create(&nd, 0); 2453 new_dentry = lookup_create(&nd, 0);
2554 error = PTR_ERR(new_dentry); 2454 error = PTR_ERR(new_dentry);
@@ -2557,7 +2457,7 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2557 error = mnt_want_write(nd.path.mnt); 2457 error = mnt_want_write(nd.path.mnt);
2558 if (error) 2458 if (error)
2559 goto out_dput; 2459 goto out_dput;
2560 error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); 2460 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
2561 mnt_drop_write(nd.path.mnt); 2461 mnt_drop_write(nd.path.mnt);
2562out_dput: 2462out_dput:
2563 dput(new_dentry); 2463 dput(new_dentry);
@@ -2565,10 +2465,9 @@ out_unlock:
2565 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2465 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2566out_release: 2466out_release:
2567 path_put(&nd.path); 2467 path_put(&nd.path);
2568out:
2569 path_put(&old_nd.path);
2570exit:
2571 putname(to); 2468 putname(to);
2469out:
2470 path_put(&old_path);
2572 2471
2573 return error; 2472 return error;
2574} 2473}
@@ -2621,7 +2520,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
2621 * we'll need to flip '..'. 2520 * we'll need to flip '..'.
2622 */ 2521 */
2623 if (new_dir != old_dir) { 2522 if (new_dir != old_dir) {
2624 error = permission(old_dentry->d_inode, MAY_WRITE, NULL); 2523 error = inode_permission(old_dentry->d_inode, MAY_WRITE);
2625 if (error) 2524 if (error)
2626 return error; 2525 return error;
2627 } 2526 }
@@ -2724,20 +2623,22 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
2724 return error; 2623 return error;
2725} 2624}
2726 2625
2727static int do_rename(int olddfd, const char *oldname, 2626asmlinkage long sys_renameat(int olddfd, const char __user *oldname,
2728 int newdfd, const char *newname) 2627 int newdfd, const char __user *newname)
2729{ 2628{
2730 int error = 0; 2629 struct dentry *old_dir, *new_dir;
2731 struct dentry * old_dir, * new_dir; 2630 struct dentry *old_dentry, *new_dentry;
2732 struct dentry * old_dentry, *new_dentry; 2631 struct dentry *trap;
2733 struct dentry * trap;
2734 struct nameidata oldnd, newnd; 2632 struct nameidata oldnd, newnd;
2633 char *from;
2634 char *to;
2635 int error;
2735 2636
2736 error = do_path_lookup(olddfd, oldname, LOOKUP_PARENT, &oldnd); 2637 error = user_path_parent(olddfd, oldname, &oldnd, &from);
2737 if (error) 2638 if (error)
2738 goto exit; 2639 goto exit;
2739 2640
2740 error = do_path_lookup(newdfd, newname, LOOKUP_PARENT, &newnd); 2641 error = user_path_parent(newdfd, newname, &newnd, &to);
2741 if (error) 2642 if (error)
2742 goto exit1; 2643 goto exit1;
2743 2644
@@ -2799,29 +2700,11 @@ exit3:
2799 unlock_rename(new_dir, old_dir); 2700 unlock_rename(new_dir, old_dir);
2800exit2: 2701exit2:
2801 path_put(&newnd.path); 2702 path_put(&newnd.path);
2703 putname(to);
2802exit1: 2704exit1:
2803 path_put(&oldnd.path); 2705 path_put(&oldnd.path);
2804exit:
2805 return error;
2806}
2807
2808asmlinkage long sys_renameat(int olddfd, const char __user *oldname,
2809 int newdfd, const char __user *newname)
2810{
2811 int error;
2812 char * from;
2813 char * to;
2814
2815 from = getname(oldname);
2816 if(IS_ERR(from))
2817 return PTR_ERR(from);
2818 to = getname(newname);
2819 error = PTR_ERR(to);
2820 if (!IS_ERR(to)) {
2821 error = do_rename(olddfd, from, newdfd, to);
2822 putname(to);
2823 }
2824 putname(from); 2706 putname(from);
2707exit:
2825 return error; 2708 return error;
2826} 2709}
2827 2710
@@ -2959,8 +2842,7 @@ const struct inode_operations page_symlink_inode_operations = {
2959 .put_link = page_put_link, 2842 .put_link = page_put_link,
2960}; 2843};
2961 2844
2962EXPORT_SYMBOL(__user_walk); 2845EXPORT_SYMBOL(user_path_at);
2963EXPORT_SYMBOL(__user_walk_fd);
2964EXPORT_SYMBOL(follow_down); 2846EXPORT_SYMBOL(follow_down);
2965EXPORT_SYMBOL(follow_up); 2847EXPORT_SYMBOL(follow_up);
2966EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ 2848EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
@@ -2975,7 +2857,7 @@ EXPORT_SYMBOL(page_symlink);
2975EXPORT_SYMBOL(page_symlink_inode_operations); 2857EXPORT_SYMBOL(page_symlink_inode_operations);
2976EXPORT_SYMBOL(path_lookup); 2858EXPORT_SYMBOL(path_lookup);
2977EXPORT_SYMBOL(vfs_path_lookup); 2859EXPORT_SYMBOL(vfs_path_lookup);
2978EXPORT_SYMBOL(permission); 2860EXPORT_SYMBOL(inode_permission);
2979EXPORT_SYMBOL(vfs_permission); 2861EXPORT_SYMBOL(vfs_permission);
2980EXPORT_SYMBOL(file_permission); 2862EXPORT_SYMBOL(file_permission);
2981EXPORT_SYMBOL(unlock_rename); 2863EXPORT_SYMBOL(unlock_rename);