Browse Source

let path_init() failures treated the same way as subsequent link_path_walk()

As it is, path_lookupat() and path_mounpoint() might end up leaking struct file
reference in some cases.

Spotted-by: Eric Biggers <ebiggers3@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Al Viro 11 years ago
parent
commit
115cbfdc60
1 changed files with 3 additions and 2 deletions
  1. 3 2
      fs/namei.c

+ 3 - 2
fs/namei.c

@@ -1950,7 +1950,7 @@ static int path_lookupat(int dfd, const char *name,
 	err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base);
 	err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base);
 
 
 	if (unlikely(err))
 	if (unlikely(err))
-		return err;
+		goto out;
 
 
 	current->total_link_count = 0;
 	current->total_link_count = 0;
 	err = link_path_walk(name, nd);
 	err = link_path_walk(name, nd);
@@ -1982,6 +1982,7 @@ static int path_lookupat(int dfd, const char *name,
 		}
 		}
 	}
 	}
 
 
+out:
 	if (base)
 	if (base)
 		fput(base);
 		fput(base);
 
 
@@ -2301,7 +2302,7 @@ path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags
 
 
 	err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base);
 	err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base);
 	if (unlikely(err))
 	if (unlikely(err))
-		return err;
+		goto out;
 
 
 	current->total_link_count = 0;
 	current->total_link_count = 0;
 	err = link_path_walk(name, &nd);
 	err = link_path_walk(name, &nd);