aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namei.c154
-rw-r--r--fs/ocfs2/refcounttree.c49
-rw-r--r--include/linux/namei.h2
-rw-r--r--net/unix/af_unix.c38
4 files changed, 106 insertions, 137 deletions
diff --git a/fs/namei.c b/fs/namei.c
index f49d6abfa799..b292eb03d9d2 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2311,6 +2311,35 @@ fail:
2311} 2311}
2312EXPORT_SYMBOL_GPL(lookup_create); 2312EXPORT_SYMBOL_GPL(lookup_create);
2313 2313
2314struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path, int is_dir)
2315{
2316 struct nameidata nd;
2317 struct dentry *res;
2318 int error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd);
2319 if (error)
2320 return ERR_PTR(error);
2321 res = lookup_create(&nd, is_dir);
2322 if (IS_ERR(res)) {
2323 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2324 path_put(&nd.path);
2325 }
2326 *path = nd.path;
2327 return res;
2328}
2329EXPORT_SYMBOL(kern_path_create);
2330
2331struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir)
2332{
2333 char *tmp = getname(pathname);
2334 struct dentry *res;
2335 if (IS_ERR(tmp))
2336 return ERR_CAST(tmp);
2337 res = kern_path_create(dfd, tmp, path, is_dir);
2338 putname(tmp);
2339 return res;
2340}
2341EXPORT_SYMBOL(user_path_create);
2342
2314int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) 2343int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
2315{ 2344{
2316 int error = may_create(dir, dentry); 2345 int error = may_create(dir, dentry);
@@ -2359,54 +2388,46 @@ static int may_mknod(mode_t mode)
2359SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, 2388SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode,
2360 unsigned, dev) 2389 unsigned, dev)
2361{ 2390{
2362 int error;
2363 char *tmp;
2364 struct dentry *dentry; 2391 struct dentry *dentry;
2365 struct nameidata nd; 2392 struct path path;
2393 int error;
2366 2394
2367 if (S_ISDIR(mode)) 2395 if (S_ISDIR(mode))
2368 return -EPERM; 2396 return -EPERM;
2369 2397
2370 error = user_path_parent(dfd, filename, &nd, &tmp); 2398 dentry = user_path_create(dfd, filename, &path, 0);
2371 if (error) 2399 if (IS_ERR(dentry))
2372 return error; 2400 return PTR_ERR(dentry);
2373 2401
2374 dentry = lookup_create(&nd, 0); 2402 if (!IS_POSIXACL(path.dentry->d_inode))
2375 if (IS_ERR(dentry)) {
2376 error = PTR_ERR(dentry);
2377 goto out_unlock;
2378 }
2379 if (!IS_POSIXACL(nd.path.dentry->d_inode))
2380 mode &= ~current_umask(); 2403 mode &= ~current_umask();
2381 error = may_mknod(mode); 2404 error = may_mknod(mode);
2382 if (error) 2405 if (error)
2383 goto out_dput; 2406 goto out_dput;
2384 error = mnt_want_write(nd.path.mnt); 2407 error = mnt_want_write(path.mnt);
2385 if (error) 2408 if (error)
2386 goto out_dput; 2409 goto out_dput;
2387 error = security_path_mknod(&nd.path, dentry, mode, dev); 2410 error = security_path_mknod(&path, dentry, mode, dev);
2388 if (error) 2411 if (error)
2389 goto out_drop_write; 2412 goto out_drop_write;
2390 switch (mode & S_IFMT) { 2413 switch (mode & S_IFMT) {
2391 case 0: case S_IFREG: 2414 case 0: case S_IFREG:
2392 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,NULL); 2415 error = vfs_create(path.dentry->d_inode,dentry,mode,NULL);
2393 break; 2416 break;
2394 case S_IFCHR: case S_IFBLK: 2417 case S_IFCHR: case S_IFBLK:
2395 error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode, 2418 error = vfs_mknod(path.dentry->d_inode,dentry,mode,
2396 new_decode_dev(dev)); 2419 new_decode_dev(dev));
2397 break; 2420 break;
2398 case S_IFIFO: case S_IFSOCK: 2421 case S_IFIFO: case S_IFSOCK:
2399 error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); 2422 error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
2400 break; 2423 break;
2401 } 2424 }
2402out_drop_write: 2425out_drop_write:
2403 mnt_drop_write(nd.path.mnt); 2426 mnt_drop_write(path.mnt);
2404out_dput: 2427out_dput:
2405 dput(dentry); 2428 dput(dentry);
2406out_unlock: 2429 mutex_unlock(&path.dentry->d_inode->i_mutex);
2407 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2430 path_put(&path);
2408 path_put(&nd.path);
2409 putname(tmp);
2410 2431
2411 return error; 2432 return error;
2412} 2433}
@@ -2439,38 +2460,29 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
2439 2460
2440SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode) 2461SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode)
2441{ 2462{
2442 int error = 0;
2443 char * tmp;
2444 struct dentry *dentry; 2463 struct dentry *dentry;
2445 struct nameidata nd; 2464 struct path path;
2446 2465 int error;
2447 error = user_path_parent(dfd, pathname, &nd, &tmp);
2448 if (error)
2449 goto out_err;
2450 2466
2451 dentry = lookup_create(&nd, 1); 2467 dentry = user_path_create(dfd, pathname, &path, 1);
2452 error = PTR_ERR(dentry);
2453 if (IS_ERR(dentry)) 2468 if (IS_ERR(dentry))
2454 goto out_unlock; 2469 return PTR_ERR(dentry);
2455 2470
2456 if (!IS_POSIXACL(nd.path.dentry->d_inode)) 2471 if (!IS_POSIXACL(path.dentry->d_inode))
2457 mode &= ~current_umask(); 2472 mode &= ~current_umask();
2458 error = mnt_want_write(nd.path.mnt); 2473 error = mnt_want_write(path.mnt);
2459 if (error) 2474 if (error)
2460 goto out_dput; 2475 goto out_dput;
2461 error = security_path_mkdir(&nd.path, dentry, mode); 2476 error = security_path_mkdir(&path, dentry, mode);
2462 if (error) 2477 if (error)
2463 goto out_drop_write; 2478 goto out_drop_write;
2464 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); 2479 error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
2465out_drop_write: 2480out_drop_write:
2466 mnt_drop_write(nd.path.mnt); 2481 mnt_drop_write(path.mnt);
2467out_dput: 2482out_dput:
2468 dput(dentry); 2483 dput(dentry);
2469out_unlock: 2484 mutex_unlock(&path.dentry->d_inode->i_mutex);
2470 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2485 path_put(&path);
2471 path_put(&nd.path);
2472 putname(tmp);
2473out_err:
2474 return error; 2486 return error;
2475} 2487}
2476 2488
@@ -2730,38 +2742,31 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
2730{ 2742{
2731 int error; 2743 int error;
2732 char *from; 2744 char *from;
2733 char *to;
2734 struct dentry *dentry; 2745 struct dentry *dentry;
2735 struct nameidata nd; 2746 struct path path;
2736 2747
2737 from = getname(oldname); 2748 from = getname(oldname);
2738 if (IS_ERR(from)) 2749 if (IS_ERR(from))
2739 return PTR_ERR(from); 2750 return PTR_ERR(from);
2740 2751
2741 error = user_path_parent(newdfd, newname, &nd, &to); 2752 dentry = user_path_create(newdfd, newname, &path, 0);
2742 if (error)
2743 goto out_putname;
2744
2745 dentry = lookup_create(&nd, 0);
2746 error = PTR_ERR(dentry); 2753 error = PTR_ERR(dentry);
2747 if (IS_ERR(dentry)) 2754 if (IS_ERR(dentry))
2748 goto out_unlock; 2755 goto out_putname;
2749 2756
2750 error = mnt_want_write(nd.path.mnt); 2757 error = mnt_want_write(path.mnt);
2751 if (error) 2758 if (error)
2752 goto out_dput; 2759 goto out_dput;
2753 error = security_path_symlink(&nd.path, dentry, from); 2760 error = security_path_symlink(&path, dentry, from);
2754 if (error) 2761 if (error)
2755 goto out_drop_write; 2762 goto out_drop_write;
2756 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); 2763 error = vfs_symlink(path.dentry->d_inode, dentry, from);
2757out_drop_write: 2764out_drop_write:
2758 mnt_drop_write(nd.path.mnt); 2765 mnt_drop_write(path.mnt);
2759out_dput: 2766out_dput:
2760 dput(dentry); 2767 dput(dentry);
2761out_unlock: 2768 mutex_unlock(&path.dentry->d_inode->i_mutex);
2762 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2769 path_put(&path);
2763 path_put(&nd.path);
2764 putname(to);
2765out_putname: 2770out_putname:
2766 putname(from); 2771 putname(from);
2767 return error; 2772 return error;
@@ -2826,11 +2831,9 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
2826 int, newdfd, const char __user *, newname, int, flags) 2831 int, newdfd, const char __user *, newname, int, flags)
2827{ 2832{
2828 struct dentry *new_dentry; 2833 struct dentry *new_dentry;
2829 struct nameidata nd; 2834 struct path old_path, new_path;
2830 struct path old_path;
2831 int how = 0; 2835 int how = 0;
2832 int error; 2836 int error;
2833 char *to;
2834 2837
2835 if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) 2838 if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
2836 return -EINVAL; 2839 return -EINVAL;
@@ -2852,32 +2855,27 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
2852 if (error) 2855 if (error)
2853 return error; 2856 return error;
2854 2857
2855 error = user_path_parent(newdfd, newname, &nd, &to); 2858 new_dentry = user_path_create(newdfd, newname, &new_path, 0);
2856 if (error)
2857 goto out;
2858 error = -EXDEV;
2859 if (old_path.mnt != nd.path.mnt)
2860 goto out_release;
2861 new_dentry = lookup_create(&nd, 0);
2862 error = PTR_ERR(new_dentry); 2859 error = PTR_ERR(new_dentry);
2863 if (IS_ERR(new_dentry)) 2860 if (IS_ERR(new_dentry))
2864 goto out_unlock; 2861 goto out;
2865 error = mnt_want_write(nd.path.mnt); 2862
2863 error = -EXDEV;
2864 if (old_path.mnt != new_path.mnt)
2865 goto out_dput;
2866 error = mnt_want_write(new_path.mnt);
2866 if (error) 2867 if (error)
2867 goto out_dput; 2868 goto out_dput;
2868 error = security_path_link(old_path.dentry, &nd.path, new_dentry); 2869 error = security_path_link(old_path.dentry, &new_path, new_dentry);
2869 if (error) 2870 if (error)
2870 goto out_drop_write; 2871 goto out_drop_write;
2871 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); 2872 error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry);
2872out_drop_write: 2873out_drop_write:
2873 mnt_drop_write(nd.path.mnt); 2874 mnt_drop_write(new_path.mnt);
2874out_dput: 2875out_dput:
2875 dput(new_dentry); 2876 dput(new_dentry);
2876out_unlock: 2877 mutex_unlock(&new_path.dentry->d_inode->i_mutex);
2877 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2878 path_put(&new_path);
2878out_release:
2879 path_put(&nd.path);
2880 putname(to);
2881out: 2879out:
2882 path_put(&old_path); 2880 path_put(&old_path);
2883 2881
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index ebfd3825f12a..cf7823382664 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -4368,25 +4368,6 @@ static inline int ocfs2_may_create(struct inode *dir, struct dentry *child)
4368 return inode_permission(dir, MAY_WRITE | MAY_EXEC); 4368 return inode_permission(dir, MAY_WRITE | MAY_EXEC);
4369} 4369}
4370 4370
4371/* copied from user_path_parent. */
4372static int ocfs2_user_path_parent(const char __user *path,
4373 struct nameidata *nd, char **name)
4374{
4375 char *s = getname(path);
4376 int error;
4377
4378 if (IS_ERR(s))
4379 return PTR_ERR(s);
4380
4381 error = kern_path_parent(s, nd);
4382 if (error)
4383 putname(s);
4384 else
4385 *name = s;
4386
4387 return error;
4388}
4389
4390/** 4371/**
4391 * ocfs2_vfs_reflink - Create a reference-counted link 4372 * ocfs2_vfs_reflink - Create a reference-counted link
4392 * 4373 *
@@ -4460,10 +4441,8 @@ int ocfs2_reflink_ioctl(struct inode *inode,
4460 bool preserve) 4441 bool preserve)
4461{ 4442{
4462 struct dentry *new_dentry; 4443 struct dentry *new_dentry;
4463 struct nameidata nd; 4444 struct path old_path, new_path;
4464 struct path old_path;
4465 int error; 4445 int error;
4466 char *to = NULL;
4467 4446
4468 if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) 4447 if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)))
4469 return -EOPNOTSUPP; 4448 return -EOPNOTSUPP;
@@ -4474,39 +4453,33 @@ int ocfs2_reflink_ioctl(struct inode *inode,
4474 return error; 4453 return error;
4475 } 4454 }
4476 4455
4477 error = ocfs2_user_path_parent(newname, &nd, &to); 4456 new_dentry = user_path_create(AT_FDCWD, newname, &new_path, 0);
4478 if (error) { 4457 error = PTR_ERR(new_dentry);
4458 if (IS_ERR(new_dentry)) {
4479 mlog_errno(error); 4459 mlog_errno(error);
4480 goto out; 4460 goto out;
4481 } 4461 }
4482 4462
4483 error = -EXDEV; 4463 error = -EXDEV;
4484 if (old_path.mnt != nd.path.mnt) 4464 if (old_path.mnt != new_path.mnt) {
4485 goto out_release;
4486 new_dentry = lookup_create(&nd, 0);
4487 error = PTR_ERR(new_dentry);
4488 if (IS_ERR(new_dentry)) {
4489 mlog_errno(error); 4465 mlog_errno(error);
4490 goto out_unlock; 4466 goto out_dput;
4491 } 4467 }
4492 4468
4493 error = mnt_want_write(nd.path.mnt); 4469 error = mnt_want_write(new_path.mnt);
4494 if (error) { 4470 if (error) {
4495 mlog_errno(error); 4471 mlog_errno(error);
4496 goto out_dput; 4472 goto out_dput;
4497 } 4473 }
4498 4474
4499 error = ocfs2_vfs_reflink(old_path.dentry, 4475 error = ocfs2_vfs_reflink(old_path.dentry,
4500 nd.path.dentry->d_inode, 4476 new_path.dentry->d_inode,
4501 new_dentry, preserve); 4477 new_dentry, preserve);
4502 mnt_drop_write(nd.path.mnt); 4478 mnt_drop_write(new_path.mnt);
4503out_dput: 4479out_dput:
4504 dput(new_dentry); 4480 dput(new_dentry);
4505out_unlock: 4481 mutex_unlock(&new_path.dentry->d_inode->i_mutex);
4506 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 4482 path_put(&new_path);
4507out_release:
4508 path_put(&nd.path);
4509 putname(to);
4510out: 4483out:
4511 path_put(&old_path); 4484 path_put(&old_path);
4512 4485
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 3439ab862e1d..b8cea804d31a 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -74,6 +74,8 @@ extern int user_path_at(int, const char __user *, unsigned, struct path *);
74 74
75extern int kern_path(const char *, unsigned, struct path *); 75extern int kern_path(const char *, unsigned, struct path *);
76 76
77extern struct dentry *kern_path_create(int, const char *, struct path *, int);
78extern struct dentry *user_path_create(int, const char __user *, struct path *, int);
77extern int kern_path_parent(const char *, struct nameidata *); 79extern int kern_path_parent(const char *, struct nameidata *);
78extern int vfs_path_lookup(struct dentry *, struct vfsmount *, 80extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
79 const char *, unsigned int, struct nameidata *); 81 const char *, unsigned int, struct nameidata *);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 0722a25a3a33..ec68e1c05b85 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -808,8 +808,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
808 struct net *net = sock_net(sk); 808 struct net *net = sock_net(sk);
809 struct unix_sock *u = unix_sk(sk); 809 struct unix_sock *u = unix_sk(sk);
810 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr; 810 struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
811 char *sun_path = sunaddr->sun_path;
811 struct dentry *dentry = NULL; 812 struct dentry *dentry = NULL;
812 struct nameidata nd; 813 struct path path;
813 int err; 814 int err;
814 unsigned hash; 815 unsigned hash;
815 struct unix_address *addr; 816 struct unix_address *addr;
@@ -845,48 +846,44 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
845 addr->hash = hash ^ sk->sk_type; 846 addr->hash = hash ^ sk->sk_type;
846 atomic_set(&addr->refcnt, 1); 847 atomic_set(&addr->refcnt, 1);
847 848
848 if (sunaddr->sun_path[0]) { 849 if (sun_path[0]) {
849 unsigned int mode; 850 unsigned int mode;
850 err = 0; 851 err = 0;
851 /* 852 /*
852 * Get the parent directory, calculate the hash for last 853 * Get the parent directory, calculate the hash for last
853 * component. 854 * component.
854 */ 855 */
855 err = kern_path_parent(sunaddr->sun_path, &nd); 856 dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
856 if (err)
857 goto out_mknod_parent;
858
859 dentry = lookup_create(&nd, 0);
860 err = PTR_ERR(dentry); 857 err = PTR_ERR(dentry);
861 if (IS_ERR(dentry)) 858 if (IS_ERR(dentry))
862 goto out_mknod_unlock; 859 goto out_mknod_parent;
863 860
864 /* 861 /*
865 * All right, let's create it. 862 * All right, let's create it.
866 */ 863 */
867 mode = S_IFSOCK | 864 mode = S_IFSOCK |
868 (SOCK_INODE(sock)->i_mode & ~current_umask()); 865 (SOCK_INODE(sock)->i_mode & ~current_umask());
869 err = mnt_want_write(nd.path.mnt); 866 err = mnt_want_write(path.mnt);
870 if (err) 867 if (err)
871 goto out_mknod_dput; 868 goto out_mknod_dput;
872 err = security_path_mknod(&nd.path, dentry, mode, 0); 869 err = security_path_mknod(&path, dentry, mode, 0);
873 if (err) 870 if (err)
874 goto out_mknod_drop_write; 871 goto out_mknod_drop_write;
875 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); 872 err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
876out_mknod_drop_write: 873out_mknod_drop_write:
877 mnt_drop_write(nd.path.mnt); 874 mnt_drop_write(path.mnt);
878 if (err) 875 if (err)
879 goto out_mknod_dput; 876 goto out_mknod_dput;
880 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 877 mutex_unlock(&path.dentry->d_inode->i_mutex);
881 dput(nd.path.dentry); 878 dput(path.dentry);
882 nd.path.dentry = dentry; 879 path.dentry = dentry;
883 880
884 addr->hash = UNIX_HASH_SIZE; 881 addr->hash = UNIX_HASH_SIZE;
885 } 882 }
886 883
887 spin_lock(&unix_table_lock); 884 spin_lock(&unix_table_lock);
888 885
889 if (!sunaddr->sun_path[0]) { 886 if (!sun_path[0]) {
890 err = -EADDRINUSE; 887 err = -EADDRINUSE;
891 if (__unix_find_socket_byname(net, sunaddr, addr_len, 888 if (__unix_find_socket_byname(net, sunaddr, addr_len,
892 sk->sk_type, hash)) { 889 sk->sk_type, hash)) {
@@ -897,8 +894,8 @@ out_mknod_drop_write:
897 list = &unix_socket_table[addr->hash]; 894 list = &unix_socket_table[addr->hash];
898 } else { 895 } else {
899 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; 896 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
900 u->dentry = nd.path.dentry; 897 u->dentry = path.dentry;
901 u->mnt = nd.path.mnt; 898 u->mnt = path.mnt;
902 } 899 }
903 900
904 err = 0; 901 err = 0;
@@ -915,9 +912,8 @@ out:
915 912
916out_mknod_dput: 913out_mknod_dput:
917 dput(dentry); 914 dput(dentry);
918out_mknod_unlock: 915 mutex_unlock(&path.dentry->d_inode->i_mutex);
919 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 916 path_put(&path);
920 path_put(&nd.path);
921out_mknod_parent: 917out_mknod_parent:
922 if (err == -EEXIST) 918 if (err == -EEXIST)
923 err = -EADDRINUSE; 919 err = -EADDRINUSE;