diff --git a/fs/namei.c b/fs/namei.c index 6868699272bf..19190618695f 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2175,15 +2175,19 @@ int user_path_at(int dfd, const char __user *name, unsigned flags, * path-walking is complete. */ static struct filename * -user_path_parent(int dfd, const char __user *path, struct nameidata *nd) +user_path_parent(int dfd, const char __user *path, struct nameidata *nd, + unsigned int flags) { struct filename *s = getname(path); int error; + /* only LOOKUP_REVAL is allowed in extra flags */ + flags &= LOOKUP_REVAL; + if (IS_ERR(s)) return s; - error = filename_lookup(dfd, s, LOOKUP_PARENT, nd); + error = filename_lookup(dfd, s, flags | LOOKUP_PARENT, nd); if (error) { putname(s); return ERR_PTR(error); @@ -3336,7 +3340,7 @@ static long do_rmdir(int dfd, const char __user *pathname) struct dentry *dentry; struct nameidata nd; - name = user_path_parent(dfd, pathname, &nd); + name = user_path_parent(dfd, pathname, &nd, 0); if (IS_ERR(name)) return PTR_ERR(name); @@ -3432,7 +3436,7 @@ static long do_unlinkat(int dfd, const char __user *pathname) struct nameidata nd; struct inode *inode = NULL; - name = user_path_parent(dfd, pathname, &nd); + name = user_path_parent(dfd, pathname, &nd, 0); if (IS_ERR(name)) return PTR_ERR(name); @@ -3827,13 +3831,13 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, struct filename *to; int error; - from = user_path_parent(olddfd, oldname, &oldnd); + from = user_path_parent(olddfd, oldname, &oldnd, 0); if (IS_ERR(from)) { error = PTR_ERR(from); goto exit; } - to = user_path_parent(newdfd, newname, &newnd); + to = user_path_parent(newdfd, newname, &newnd, 0); if (IS_ERR(to)) { error = PTR_ERR(to); goto exit1;