aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-03-14 18:56:51 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-03-14 19:12:20 -0400
commitf52e0c11305aa09ed56cad97ffc8f0cdc3d78b5d (patch)
treeb04070034f8a941fe5d7e9e1b335a02784686bd5 /fs/namei.c
parent5fe0c2378884e68beb532f5890cc0e3539ac747b (diff)
New AT_... flag: AT_EMPTY_PATH
For name_to_handle_at(2) we'll want both ...at()-style syscall that would be usable for non-directory descriptors (with empty relative pathname). Introduce new flag (AT_EMPTY_PATH) to deal with that and corresponding LOOKUP_EMPTY; teach user_path_at() and path_init() to deal with the latter. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/fs/namei.c b/fs/namei.c
index abc8d2df121c..83e92bab79a6 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -136,7 +136,7 @@ static int do_getname(const char __user *filename, char *page)
136 return retval; 136 return retval;
137} 137}
138 138
139char * getname(const char __user * filename) 139static char *getname_flags(const char __user * filename, int flags)
140{ 140{
141 char *tmp, *result; 141 char *tmp, *result;
142 142
@@ -147,14 +147,21 @@ char * getname(const char __user * filename)
147 147
148 result = tmp; 148 result = tmp;
149 if (retval < 0) { 149 if (retval < 0) {
150 __putname(tmp); 150 if (retval != -ENOENT || !(flags & LOOKUP_EMPTY)) {
151 result = ERR_PTR(retval); 151 __putname(tmp);
152 result = ERR_PTR(retval);
153 }
152 } 154 }
153 } 155 }
154 audit_getname(result); 156 audit_getname(result);
155 return result; 157 return result;
156} 158}
157 159
160char *getname(const char __user * filename)
161{
162 return getname_flags(filename, 0);
163}
164
158#ifdef CONFIG_AUDITSYSCALL 165#ifdef CONFIG_AUDITSYSCALL
159void putname(const char *name) 166void putname(const char *name)
160{ 167{
@@ -1544,13 +1551,15 @@ static int path_init(int dfd, const char *name, unsigned int flags,
1544 1551
1545 dentry = file->f_path.dentry; 1552 dentry = file->f_path.dentry;
1546 1553
1547 retval = -ENOTDIR; 1554 if (*name) {
1548 if (!S_ISDIR(dentry->d_inode->i_mode)) 1555 retval = -ENOTDIR;
1549 goto fput_fail; 1556 if (!S_ISDIR(dentry->d_inode->i_mode))
1557 goto fput_fail;
1550 1558
1551 retval = file_permission(file, MAY_EXEC); 1559 retval = file_permission(file, MAY_EXEC);
1552 if (retval) 1560 if (retval)
1553 goto fput_fail; 1561 goto fput_fail;
1562 }
1554 1563
1555 nd->path = file->f_path; 1564 nd->path = file->f_path;
1556 if (flags & LOOKUP_RCU) { 1565 if (flags & LOOKUP_RCU) {
@@ -1759,7 +1768,7 @@ int user_path_at(int dfd, const char __user *name, unsigned flags,
1759 struct path *path) 1768 struct path *path)
1760{ 1769{
1761 struct nameidata nd; 1770 struct nameidata nd;
1762 char *tmp = getname(name); 1771 char *tmp = getname_flags(name, flags);
1763 int err = PTR_ERR(tmp); 1772 int err = PTR_ERR(tmp);
1764 if (!IS_ERR(tmp)) { 1773 if (!IS_ERR(tmp)) {
1765 1774