Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull fs fixes from Al Viro:
 "Fairly old hostfs bug (in setups that are not used by anyone,
  apparently) + fix for this cycle regression: extra dput/mntput in
  LOOKUP_CACHED failure handling"

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  Make sure nd->path.mnt and nd->path.dentry are always valid pointers
  hostfs: fix memory handling in follow_link()
This commit is contained in:
Linus Torvalds 2021-04-06 12:52:49 -07:00
commit 2d74366078
2 changed files with 7 additions and 6 deletions

View File

@ -144,7 +144,7 @@ static char *follow_link(char *link)
char *name, *resolved, *end; char *name, *resolved, *end;
int n; int n;
name = __getname(); name = kmalloc(PATH_MAX, GFP_KERNEL);
if (!name) { if (!name) {
n = -ENOMEM; n = -ENOMEM;
goto out_free; goto out_free;
@ -173,12 +173,11 @@ static char *follow_link(char *link)
goto out_free; goto out_free;
} }
__putname(name); kfree(name);
kfree(link);
return resolved; return resolved;
out_free: out_free:
__putname(name); kfree(name);
return ERR_PTR(n); return ERR_PTR(n);
} }

View File

@ -579,6 +579,8 @@ static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
p->stack = p->internal; p->stack = p->internal;
p->dfd = dfd; p->dfd = dfd;
p->name = name; p->name = name;
p->path.mnt = NULL;
p->path.dentry = NULL;
p->total_link_count = old ? old->total_link_count : 0; p->total_link_count = old ? old->total_link_count : 0;
p->saved = old; p->saved = old;
current->nameidata = p; current->nameidata = p;
@ -652,6 +654,8 @@ static void terminate_walk(struct nameidata *nd)
rcu_read_unlock(); rcu_read_unlock();
} }
nd->depth = 0; nd->depth = 0;
nd->path.mnt = NULL;
nd->path.dentry = NULL;
} }
/* path_put is needed afterwards regardless of success or failure */ /* path_put is needed afterwards regardless of success or failure */
@ -2322,8 +2326,6 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
} }
nd->root.mnt = NULL; nd->root.mnt = NULL;
nd->path.mnt = NULL;
nd->path.dentry = NULL;
/* Absolute pathname -- fetch the root (LOOKUP_IN_ROOT uses nd->dfd). */ /* Absolute pathname -- fetch the root (LOOKUP_IN_ROOT uses nd->dfd). */
if (*s == '/' && !(flags & LOOKUP_IN_ROOT)) { if (*s == '/' && !(flags & LOOKUP_IN_ROOT)) {