|
@@ -137,7 +137,7 @@ static int do_getname(const char __user *filename, char *page)
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-static char *getname_flags(const char __user * filename, int flags)
|
|
|
+static char *getname_flags(const char __user *filename, int flags, int *empty)
|
|
|
{
|
|
|
char *tmp, *result;
|
|
|
|
|
@@ -148,6 +148,8 @@ static char *getname_flags(const char __user * filename, int flags)
|
|
|
|
|
|
result = tmp;
|
|
|
if (retval < 0) {
|
|
|
+ if (retval == -ENOENT && empty)
|
|
|
+ *empty = 1;
|
|
|
if (retval != -ENOENT || !(flags & LOOKUP_EMPTY)) {
|
|
|
__putname(tmp);
|
|
|
result = ERR_PTR(retval);
|
|
@@ -160,7 +162,7 @@ static char *getname_flags(const char __user * filename, int flags)
|
|
|
|
|
|
char *getname(const char __user * filename)
|
|
|
{
|
|
|
- return getname_flags(filename, 0);
|
|
|
+ return getname_flags(filename, 0, 0);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_AUDITSYSCALL
|
|
@@ -1798,11 +1800,11 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
|
|
|
return __lookup_hash(&this, base, NULL);
|
|
|
}
|
|
|
|
|
|
-int user_path_at(int dfd, const char __user *name, unsigned flags,
|
|
|
- struct path *path)
|
|
|
+int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
|
|
|
+ struct path *path, int *empty)
|
|
|
{
|
|
|
struct nameidata nd;
|
|
|
- char *tmp = getname_flags(name, flags);
|
|
|
+ char *tmp = getname_flags(name, flags, empty);
|
|
|
int err = PTR_ERR(tmp);
|
|
|
if (!IS_ERR(tmp)) {
|
|
|
|
|
@@ -1816,6 +1818,12 @@ int user_path_at(int dfd, const char __user *name, unsigned flags,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+int user_path_at(int dfd, const char __user *name, unsigned flags,
|
|
|
+ struct path *path)
|
|
|
+{
|
|
|
+ return user_path_at_empty(dfd, name, flags, path, 0);
|
|
|
+}
|
|
|
+
|
|
|
static int user_path_parent(int dfd, const char __user *path,
|
|
|
struct nameidata *nd, char **name)
|
|
|
{
|