fix proc_fill_cache() in case of d_alloc_parallel() failure
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 8 Jun 2018 05:17:11 +0000 (01:17 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 8 Jun 2018 05:17:11 +0000 (01:17 -0400)
If d_alloc_parallel() returns ERR_PTR(...), we don't want to dput()
that.  Small reorganization allows to have all error-in-lookup
cases rejoin the main codepath after dput(child), avoiding the
entire problem.

Spotted-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Fixes: 0168b9e38c42 "procfs: switch instantiate_t to d_splice_alias()"
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/proc/base.c

index de22c2002b38202a6fb287b4ced65442ad141e88..6f927340db0a5f854975f0c9180ea57bdf47b8e6 100644 (file)
@@ -1891,19 +1891,19 @@ bool proc_fill_cache(struct file *file, struct dir_context *ctx,
                        struct dentry *res;
                        res = instantiate(child, task, ptr);
                        d_lookup_done(child);
-                       if (IS_ERR(res))
-                               goto end_instantiate;
                        if (unlikely(res)) {
                                dput(child);
                                child = res;
+                               if (IS_ERR(child))
+                                       goto end_instantiate;
                        }
                }
        }
        inode = d_inode(child);
        ino = inode->i_ino;
        type = inode->i_mode >> 12;
-end_instantiate:
        dput(child);
+end_instantiate:
        return dir_emit(ctx, name, len, ino, type);
 }