linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] namei: get rid of unused filename_parentat()
@ 2021-09-01 15:00 Dmitry Kadashev
  2021-09-01 15:09 ` Christoph Hellwig
  2021-09-01 15:30 ` Al Viro
  0 siblings, 2 replies; 5+ messages in thread
From: Dmitry Kadashev @ 2021-09-01 15:00 UTC (permalink / raw)
  To: Jens Axboe, Alexander Viro, Christoph Hellwig, Stephen Brennan
  Cc: linux-fsdevel, linux-kernel, Dmitry Kadashev

After the switch of kern_path_locked() to __filename_parentat() (to
address use after free bug) nothing is using filename_parentat(). Also,
filename_parentat() is inherently buggy: the "last" output arg
always point to freed memory.

Drop filename_parentat() and rename __filename_parentat() to
filename_parentat().

Link: https://lore.kernel.org/linux-fsdevel/YS9D4AlEsaCxLFV0@infradead.org/
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Dmitry Kadashev <dkadashev@gmail.com>
---
On top of https://lore.kernel.org/linux-fsdevel/20210901001341.79887-1-stephen.s.brennan@oracle.com/

 fs/namei.c | 34 ++++++++++++----------------------
 1 file changed, 12 insertions(+), 22 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index a0122f0016a3..f2af301cc79f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2514,9 +2514,10 @@ static int path_parentat(struct nameidata *nd, unsigned flags,
 	return err;
 }
 
-static int __filename_parentat(int dfd, struct filename *name,
-				unsigned int flags, struct path *parent,
-				struct qstr *last, int *type)
+/* Note: this does not consume "name" */
+static int filename_parentat(int dfd, struct filename *name,
+			     unsigned int flags, struct path *parent,
+			     struct qstr *last, int *type)
 {
 	int retval;
 	struct nameidata nd;
@@ -2538,16 +2539,6 @@ static int __filename_parentat(int dfd, struct filename *name,
 	return retval;
 }
 
-static int filename_parentat(int dfd, struct filename *name,
-				unsigned int flags, struct path *parent,
-				struct qstr *last, int *type)
-{
-	int retval = __filename_parentat(dfd, name, flags, parent, last, type);
-
-	putname(name);
-	return retval;
-}
-
 /* does lookup, returns the object with parent locked */
 struct dentry *kern_path_locked(const char *name, struct path *path)
 {
@@ -2557,8 +2548,7 @@ struct dentry *kern_path_locked(const char *name, struct path *path)
 	int type, error;
 
 	filename = getname_kernel(name);
-	error = __filename_parentat(AT_FDCWD, filename, 0, path,
-				    &last, &type);
+	error = filename_parentat(AT_FDCWD, filename, 0, path, &last, &type);
 	if (error) {
 		d = ERR_PTR(error);
 		goto out;
@@ -3641,7 +3631,7 @@ static struct dentry *__filename_create(int dfd, struct filename *name,
 	 */
 	lookup_flags &= LOOKUP_REVAL;
 
-	error = __filename_parentat(dfd, name, lookup_flags, path, &last, &type);
+	error = filename_parentat(dfd, name, lookup_flags, path, &last, &type);
 	if (error)
 		return ERR_PTR(error);
 
@@ -4003,7 +3993,7 @@ int do_rmdir(int dfd, struct filename *name)
 	int type;
 	unsigned int lookup_flags = 0;
 retry:
-	error = __filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
+	error = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
 	if (error)
 		goto exit1;
 
@@ -4142,7 +4132,7 @@ int do_unlinkat(int dfd, struct filename *name)
 	struct inode *delegated_inode = NULL;
 	unsigned int lookup_flags = 0;
 retry:
-	error = __filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
+	error = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
 	if (error)
 		goto exit1;
 
@@ -4690,13 +4680,13 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd,
 		target_flags = 0;
 
 retry:
-	error = __filename_parentat(olddfd, from, lookup_flags, &old_path,
-					&old_last, &old_type);
+	error = filename_parentat(olddfd, from, lookup_flags, &old_path,
+				  &old_last, &old_type);
 	if (error)
 		goto put_names;
 
-	error = __filename_parentat(newdfd, to, lookup_flags, &new_path, &new_last,
-				&new_type);
+	error = filename_parentat(newdfd, to, lookup_flags, &new_path, &new_last,
+				  &new_type);
 	if (error)
 		goto exit1;
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] namei: get rid of unused filename_parentat()
  2021-09-01 15:00 [PATCH] namei: get rid of unused filename_parentat() Dmitry Kadashev
@ 2021-09-01 15:09 ` Christoph Hellwig
  2021-09-01 15:30 ` Al Viro
  1 sibling, 0 replies; 5+ messages in thread
From: Christoph Hellwig @ 2021-09-01 15:09 UTC (permalink / raw)
  To: Dmitry Kadashev
  Cc: Jens Axboe, Alexander Viro, Christoph Hellwig, Stephen Brennan,
	linux-fsdevel, linux-kernel

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] namei: get rid of unused filename_parentat()
  2021-09-01 15:00 [PATCH] namei: get rid of unused filename_parentat() Dmitry Kadashev
  2021-09-01 15:09 ` Christoph Hellwig
@ 2021-09-01 15:30 ` Al Viro
  2021-09-01 15:35   ` Al Viro
  1 sibling, 1 reply; 5+ messages in thread
From: Al Viro @ 2021-09-01 15:30 UTC (permalink / raw)
  To: Dmitry Kadashev
  Cc: Jens Axboe, Christoph Hellwig, Stephen Brennan, linux-fsdevel,
	linux-kernel

On Wed, Sep 01, 2021 at 10:00:40PM +0700, Dmitry Kadashev wrote:
> After the switch of kern_path_locked() to __filename_parentat() (to
> address use after free bug) nothing is using filename_parentat(). Also,
> filename_parentat() is inherently buggy: the "last" output arg
> always point to freed memory.
> 
> Drop filename_parentat() and rename __filename_parentat() to
> filename_parentat().

I'd rather fold that into previous patch.

And it might be better to fold filename_create() into its 2 callers
and rename __filename_create() as well.

Let me poke around a bit...

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] namei: get rid of unused filename_parentat()
  2021-09-01 15:30 ` Al Viro
@ 2021-09-01 15:35   ` Al Viro
  2021-09-01 16:19     ` Stephen Brennan
  0 siblings, 1 reply; 5+ messages in thread
From: Al Viro @ 2021-09-01 15:35 UTC (permalink / raw)
  To: Dmitry Kadashev
  Cc: Jens Axboe, Christoph Hellwig, Stephen Brennan, linux-fsdevel,
	linux-kernel

On Wed, Sep 01, 2021 at 03:30:56PM +0000, Al Viro wrote:
> On Wed, Sep 01, 2021 at 10:00:40PM +0700, Dmitry Kadashev wrote:
> > After the switch of kern_path_locked() to __filename_parentat() (to
> > address use after free bug) nothing is using filename_parentat(). Also,
> > filename_parentat() is inherently buggy: the "last" output arg
> > always point to freed memory.
> > 
> > Drop filename_parentat() and rename __filename_parentat() to
> > filename_parentat().
> 
> I'd rather fold that into previous patch.
> 
> And it might be better to fold filename_create() into its 2 callers
> and rename __filename_create() as well.
> 
> Let me poke around a bit...

BTW, if you look at the only caller of filename_lookup() outside of
fs/namei.c, you'll see this:
        f->refcnt++; /* filename_lookup() drops our ref. */
	ret = filename_lookup(param->dirfd, f, flags, _path, NULL);
IOW, that thing would be better off with calling the current
__filename_lookup().

Might be better to rename filename_lookup to something different,
turn __filename_lookup() into filename_lookup() and use _that_ in
fs/fs_parser.c...

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] namei: get rid of unused filename_parentat()
  2021-09-01 15:35   ` Al Viro
@ 2021-09-01 16:19     ` Stephen Brennan
  0 siblings, 0 replies; 5+ messages in thread
From: Stephen Brennan @ 2021-09-01 16:19 UTC (permalink / raw)
  To: Al Viro, Dmitry Kadashev
  Cc: Jens Axboe, Christoph Hellwig, linux-fsdevel, linux-kernel

On 9/1/21 8:35 AM, Al Viro wrote:
> On Wed, Sep 01, 2021 at 03:30:56PM +0000, Al Viro wrote:
>> On Wed, Sep 01, 2021 at 10:00:40PM +0700, Dmitry Kadashev wrote:
>>> After the switch of kern_path_locked() to __filename_parentat() (to
>>> address use after free bug) nothing is using filename_parentat(). Also,
>>> filename_parentat() is inherently buggy: the "last" output arg
>>> always point to freed memory.
>>>
>>> Drop filename_parentat() and rename __filename_parentat() to
>>> filename_parentat().
>>
>> I'd rather fold that into previous patch.
>>
>> And it might be better to fold filename_create() into its 2 callers
>> and rename __filename_create() as well.
>>
>> Let me poke around a bit...
> 
> BTW, if you look at the only caller of filename_lookup() outside of
> fs/namei.c, you'll see this:
>          f->refcnt++; /* filename_lookup() drops our ref. */
> 	ret = filename_lookup(param->dirfd, f, flags, _path, NULL);
> IOW, that thing would be better off with calling the current
> __filename_lookup().
> 
> Might be better to rename filename_lookup to something different,
> turn __filename_lookup() into filename_lookup() and use _that_ in
> fs/fs_parser.c...

The value of Dimitry's original patch was that the calling convention 
(i.e. whether the function calls putname for you) is clear from the name 
of the function: __filename_lookup doesn't call putname, and 
filename_lookup() does.

I think what we're discovering is that maybe the double-underscore 
version isn't all that useful, and can be quite confusing (leading to 
refcount increments like we see here). It's highly unusual for a 
function that's not explicitly a destructor of some kind to drop a 
reference that was passed into it.

Could we just standardize all of these filename_xxx() methods to leave 
the filename reference alone? I see the following uses:

filename_create(): 2 users in fs/namei.c, trivial to change
filename_lookup(): 3 users in fs/namei.c, also trivial
filename_parentat(): only user was fixed in my earlier patch

The cost in each function is two additional lines, in return for some 
clarity about the calling conventions, rather than creating more confusion.

Stephen

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-09-01 16:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-01 15:00 [PATCH] namei: get rid of unused filename_parentat() Dmitry Kadashev
2021-09-01 15:09 ` Christoph Hellwig
2021-09-01 15:30 ` Al Viro
2021-09-01 15:35   ` Al Viro
2021-09-01 16:19     ` Stephen Brennan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).