linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag
@ 2016-10-13 19:58 Vineeth Remanan Pillai
  2016-10-13 20:06 ` Al Viro
  2016-10-13 20:09 ` Christoph Hellwig
  0 siblings, 2 replies; 10+ messages in thread
From: Vineeth Remanan Pillai @ 2016-10-13 19:58 UTC (permalink / raw)
  To: viro, linux-fsdevel, linux-kernel
  Cc: Vineeth Remanan Pillai, kamatam, aliguori

filename_lookup used to return success for non-existing file when called
with LOOKUP_PARENT flag. This behaviour was changed with
commit 8bcb77fabd7c ("namei: split off filename_lookupat()
with LOOKUP_PARENT")

The above patch split parent lookup functionality to a different function
filename_parentat and changed all calls to filename_lookup(LOOKUP_PARENT)
to the new function filename_parentat. But functions like kern_path which
passed the flags directly to filename_lookup regressed due to this.

This patch aims to fix the regressed behaviour by calling
filename_parentat from filename_lookup if the flags contain LOOKUP_PARENT.

Signed-off-by: Vineeth Remanan Pillai <vineethp@amazon.com>
---
 fs/namei.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/fs/namei.c b/fs/namei.c
index adb0414..e16ab09 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2292,6 +2292,21 @@ static int filename_lookup(int dfd, struct filename *name, unsigned flags,
 {
 	int retval;
 	struct nameidata nd;
+
+	if (flags & LOOKUP_PARENT) {
+		struct qstr last;
+		struct filename *filename;
+		int type;
+
+		filename = filename_parentat(dfd, name, flags ^ LOOKUP_PARENT,
+					    path, &last, &type);
+		if (IS_ERR(filename))
+			return PTR_ERR(filename);
+
+		putname(filename);
+		return 0;
+	}
+
 	if (IS_ERR(name))
 		return PTR_ERR(name);
 	if (unlikely(root)) {
-- 
2.1.2.AMZN

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

* Re: [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag
  2016-10-13 19:58 [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag Vineeth Remanan Pillai
@ 2016-10-13 20:06 ` Al Viro
  2016-10-13 20:09 ` Christoph Hellwig
  1 sibling, 0 replies; 10+ messages in thread
From: Al Viro @ 2016-10-13 20:06 UTC (permalink / raw)
  To: Vineeth Remanan Pillai; +Cc: linux-fsdevel, linux-kernel, kamatam, aliguori

On Thu, Oct 13, 2016 at 07:58:51PM +0000, Vineeth Remanan Pillai wrote:
> filename_lookup used to return success for non-existing file when called
> with LOOKUP_PARENT flag. This behaviour was changed with
> commit 8bcb77fabd7c ("namei: split off filename_lookupat()
> with LOOKUP_PARENT")
> 
> The above patch split parent lookup functionality to a different function
> filename_parentat and changed all calls to filename_lookup(LOOKUP_PARENT)
> to the new function filename_parentat. But functions like kern_path which
> passed the flags directly to filename_lookup regressed due to this.
> 
> This patch aims to fix the regressed behaviour by calling
> filename_parentat from filename_lookup if the flags contain LOOKUP_PARENT.

What would we want that for?  Details, please.  In particular, I would like
to know how to use that in non-racy way.  What are you doing with it?

PS: "regressed" assumes that there had been any promise of API stability;
no such thing has ever existed.

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

* Re: [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag
  2016-10-13 19:58 [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag Vineeth Remanan Pillai
  2016-10-13 20:06 ` Al Viro
@ 2016-10-13 20:09 ` Christoph Hellwig
  2016-10-13 20:26   ` Al Viro
  1 sibling, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2016-10-13 20:09 UTC (permalink / raw)
  To: Vineeth Remanan Pillai
  Cc: viro, linux-fsdevel, linux-kernel, kamatam, aliguori

On Thu, Oct 13, 2016 at 07:58:51PM +0000, Vineeth Remanan Pillai wrote:
> filename_lookup used to return success for non-existing file when called
> with LOOKUP_PARENT flag. This behaviour was changed with
> commit 8bcb77fabd7c ("namei: split off filename_lookupat()
> with LOOKUP_PARENT")
> 
> The above patch split parent lookup functionality to a different function
> filename_parentat and changed all calls to filename_lookup(LOOKUP_PARENT)
> to the new function filename_parentat. But functions like kern_path which
> passed the flags directly to filename_lookup regressed due to this.
> 
> This patch aims to fix the regressed behaviour by calling
> filename_parentat from filename_lookup if the flags contain LOOKUP_PARENT.

What callers shows te problems?  That's probaby were the fix need to got
in, and even if not that's still part of a good bug report.

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

* Re: [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag
  2016-10-13 20:09 ` Christoph Hellwig
@ 2016-10-13 20:26   ` Al Viro
  2016-10-13 20:41     ` Vineeth Remanan Pillai
  0 siblings, 1 reply; 10+ messages in thread
From: Al Viro @ 2016-10-13 20:26 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Vineeth Remanan Pillai, linux-fsdevel, linux-kernel, kamatam, aliguori

On Thu, Oct 13, 2016 at 01:09:04PM -0700, Christoph Hellwig wrote:
> On Thu, Oct 13, 2016 at 07:58:51PM +0000, Vineeth Remanan Pillai wrote:
> > filename_lookup used to return success for non-existing file when called
> > with LOOKUP_PARENT flag. This behaviour was changed with
> > commit 8bcb77fabd7c ("namei: split off filename_lookupat()
> > with LOOKUP_PARENT")
> > 
> > The above patch split parent lookup functionality to a different function
> > filename_parentat and changed all calls to filename_lookup(LOOKUP_PARENT)
> > to the new function filename_parentat. But functions like kern_path which
> > passed the flags directly to filename_lookup regressed due to this.
> > 
> > This patch aims to fix the regressed behaviour by calling
> > filename_parentat from filename_lookup if the flags contain LOOKUP_PARENT.
> 
> What callers shows te problems?  That's probaby were the fix need to got
> in, and even if not that's still part of a good bug report.

Out-of-tree, at a guess...  Incidentally, since filename_lookup() is not
exported, it's probably kern_path() that gets used wherever it is.
Depending on the details of what's being attempted,  kern_path_locked()
might or might not be the right primitive to use, but I would probably
start with checking if that's what the code in question really wants.

Use:
	// kernel_string is an kernel pointer to NUL-terminated array of char

	struct path path;
	struct dentry *dentry;

	dentry = kern_path_locked(kernel_string, &path);
	if (IS_ERR(dentry))
		// failed while getting the parent, or not a regular last
		// component (/, ., .., <something>/., <something>/..)
		sod off // no cleanup needed

	// now path contains the resolved parent and dentry points to the
	// dentry of child, possibly negative; the last component of the
	// name can be determined from dentry->d_name.  Parent directory
	// is locked, making sure that directory entry won't be changed
	// until you are done.

	if (d_is_really_negative(dentry)) {
		// parent exists, but child doesn't
	} else {
		// child exists
	}

	// clean up: drop dentry, unlock parent, drop dentry/vfsmount of parent
	dput(dentry);
	inode_unlock(path.dentry->d_inode);
	path_put(&path);

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

* Re: [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag
  2016-10-13 20:26   ` Al Viro
@ 2016-10-13 20:41     ` Vineeth Remanan Pillai
  2016-10-13 20:44       ` Christoph Hellwig
  2016-10-13 21:24       ` Al Viro
  0 siblings, 2 replies; 10+ messages in thread
From: Vineeth Remanan Pillai @ 2016-10-13 20:41 UTC (permalink / raw)
  To: Al Viro, Christoph Hellwig; +Cc: linux-fsdevel, linux-kernel, kamatam, aliguori

On 10/13/2016 01:26 PM, Al Viro wrote:
> On Thu, Oct 13, 2016 at 01:09:04PM -0700, Christoph Hellwig wrote:
>> On Thu, Oct 13, 2016 at 07:58:51PM +0000, Vineeth Remanan Pillai wrote:
>>> filename_lookup used to return success for non-existing file when called
>>> with LOOKUP_PARENT flag. This behaviour was changed with
>>> commit 8bcb77fabd7c ("namei: split off filename_lookupat()
>>> with LOOKUP_PARENT")
>>>
>>> The above patch split parent lookup functionality to a different function
>>> filename_parentat and changed all calls to filename_lookup(LOOKUP_PARENT)
>>> to the new function filename_parentat. But functions like kern_path which
>>> passed the flags directly to filename_lookup regressed due to this.
>>>
>>> This patch aims to fix the regressed behaviour by calling
>>> filename_parentat from filename_lookup if the flags contain LOOKUP_PARENT.
>> What callers shows te problems?  That's probaby were the fix need to got
>> in, and even if not that's still part of a good bug report.
> Out-of-tree, at a guess...  Incidentally, since filename_lookup() is not
> exported, it's probably kern_path() that gets used wherever it is.
> Depending on the details of what's being attempted,  kern_path_locked()
> might or might not be the right primitive to use, but I would probably
> start with checking if that's what the code in question really wants.
>
> Use:
> 	// kernel_string is an kernel pointer to NUL-terminated array of char
>
> 	struct path path;
> 	struct dentry *dentry;
>
> 	dentry = kern_path_locked(kernel_string, &path);
> 	if (IS_ERR(dentry))
> 		// failed while getting the parent, or not a regular last
> 		// component (/, ., .., <something>/., <something>/..)
> 		sod off // no cleanup needed
>
> 	// now path contains the resolved parent and dentry points to the
> 	// dentry of child, possibly negative; the last component of the
> 	// name can be determined from dentry->d_name.  Parent directory
> 	// is locked, making sure that directory entry won't be changed
> 	// until you are done.
>
> 	if (d_is_really_negative(dentry)) {
> 		// parent exists, but child doesn't
> 	} else {
> 		// child exists
> 	}
>
> 	// clean up: drop dentry, unlock parent, drop dentry/vfsmount of parent
> 	dput(dentry);
> 	inode_unlock(path.dentry->d_inode);
> 	path_put(&path);
>
Yes, the use case is out-of-tree and the code snippet above depicts the 
use .
Since kern_path_locked is also not exported, out-of-tree code used kern_path
for the existence check for directories.

One reference about this issue can be seen here.

http://www.gossamer-threads.com/lists/linux/kernel/2459690?do=post_view_flat#2459690

We also have a customer who complained about this functionality change.

I understand that there has been no API promises been made to this API. 
But since this is an
exported function, the change in function could cause break in 
out-of-tree kernel code. I will
rephrase the commit message to say "change in functionality" instead of 
regression

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

* Re: [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag
  2016-10-13 20:41     ` Vineeth Remanan Pillai
@ 2016-10-13 20:44       ` Christoph Hellwig
  2016-10-13 21:24       ` Al Viro
  1 sibling, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2016-10-13 20:44 UTC (permalink / raw)
  To: Vineeth Remanan Pillai
  Cc: Al Viro, Christoph Hellwig, linux-fsdevel, linux-kernel, kamatam,
	aliguori

On Thu, Oct 13, 2016 at 01:41:11PM -0700, Vineeth Remanan Pillai wrote:
> Yes, the use case is out-of-tree and the code snippet above depicts the use

Case closed then.  If it doesn't affect any in-tree code please don't
bother spamming linux lists with your self-inflicted wounds.

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

* Re: [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag
  2016-10-13 20:41     ` Vineeth Remanan Pillai
  2016-10-13 20:44       ` Christoph Hellwig
@ 2016-10-13 21:24       ` Al Viro
  2016-10-13 22:14         ` Vineeth Remanan Pillai
  1 sibling, 1 reply; 10+ messages in thread
From: Al Viro @ 2016-10-13 21:24 UTC (permalink / raw)
  To: Vineeth Remanan Pillai
  Cc: Christoph Hellwig, linux-fsdevel, linux-kernel, kamatam, aliguori

On Thu, Oct 13, 2016 at 01:41:11PM -0700, Vineeth Remanan Pillai wrote:

> Yes, the use case is out-of-tree and the code snippet above depicts the use
> .
> Since kern_path_locked is also not exported, out-of-tree code used kern_path
> for the existence check for directories.
> 
> One reference about this issue can be seen here.
> 
> http://www.gossamer-threads.com/lists/linux/kernel/2459690?do=post_view_flat#2459690

... and in that thread I have asked for details and got no reply whatsoever.
 
> We also have a customer who complained about this functionality change.
> 
> I understand that there has been no API promises been made to this API. But
> since this is an
> exported function, the change in function could cause break in out-of-tree
> kernel code. I will
> rephrase the commit message to say "change in functionality" instead of
> regression

In principle, I have no strong objections against exporting kern_path_locked,
provided it really matches what they (whoever they are) need.  I'm still
curious about the context, though - what is that code trying to do?  Depending
on the actual stuff it wants to implement, there might be better primitives
for doing that *and* there might be something worth adding and exporting
that would be a better match.

It's not that kern_path_locked() isn't a sane interface, but... using it
might be a sign of trying to work around something missing in API.  So again,
please post more details.

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

* Re: [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag
  2016-10-13 21:24       ` Al Viro
@ 2016-10-13 22:14         ` Vineeth Remanan Pillai
  2016-10-13 23:31           ` Al Viro
  0 siblings, 1 reply; 10+ messages in thread
From: Vineeth Remanan Pillai @ 2016-10-13 22:14 UTC (permalink / raw)
  To: Al Viro; +Cc: Christoph Hellwig, linux-fsdevel, linux-kernel, kamatam, aliguori


On 10/13/2016 02:24 PM, Al Viro wrote:
> On Thu, Oct 13, 2016 at 01:41:11PM -0700, Vineeth Remanan Pillai wrote:
>
>> Yes, the use case is out-of-tree and the code snippet above depicts the use
>> .
>> Since kern_path_locked is also not exported, out-of-tree code used kern_path
>> for the existence check for directories.
>>
>> One reference about this issue can be seen here.
>>
>> http://www.gossamer-threads.com/lists/linux/kernel/2459690?do=post_view_flat#2459690
> ... and in that thread I have asked for details and got no reply whatsoever.
>   
>> We also have a customer who complained about this functionality change.
>>
>> I understand that there has been no API promises been made to this API. But
>> since this is an
>> exported function, the change in function could cause break in out-of-tree
>> kernel code. I will
>> rephrase the commit message to say "change in functionality" instead of
>> regression
> In principle, I have no strong objections against exporting kern_path_locked,
> provided it really matches what they (whoever they are) need.  I'm still
> curious about the context, though - what is that code trying to do?  Depending
> on the actual stuff it wants to implement, there might be better primitives
> for doing that *and* there might be something worth adding and exporting
> that would be a better match.
>
> It's not that kern_path_locked() isn't a sane interface, but... using it
> might be a sign of trying to work around something missing in API.  So again,
> please post more details.
Unfortunately, I also do not have enough context about the customer
code that uses it. Since kern_path was exported function and the
behavior changed across releases, this patch is just trying to revert
to the old behavior.
I clearly get what you are trying to say. It would have been really
beneficial to get the context so as to understand use case and figure out
alternative or better approach. But I think we should have the functionality
as before and if kern_path is not the right API for this purpose, 
probably we
should deprecate it in a phased manner.

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

* Re: [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag
  2016-10-13 22:14         ` Vineeth Remanan Pillai
@ 2016-10-13 23:31           ` Al Viro
  2016-10-14  0:02             ` Remanan Pillai, Vineeth
  0 siblings, 1 reply; 10+ messages in thread
From: Al Viro @ 2016-10-13 23:31 UTC (permalink / raw)
  To: Vineeth Remanan Pillai
  Cc: Christoph Hellwig, linux-fsdevel, linux-kernel, kamatam, aliguori

On Thu, Oct 13, 2016 at 03:14:23PM -0700, Vineeth Remanan Pillai wrote:
> Unfortunately, I also do not have enough context about the customer
> code that uses it. Since kern_path was exported function and the
> behavior changed across releases, this patch is just trying to revert
> to the old behavior.
> I clearly get what you are trying to say. It would have been really
> beneficial to get the context so as to understand use case and figure out
> alternative or better approach. But I think we should have the functionality
> as before and if kern_path is not the right API for this purpose, probably
> we
> should deprecate it in a phased manner.

kern_path() is not the right API for this purpose.  Never had been.  It is,
OTOH, the right API for other purposes, so it's not going to disappear.
If you check the history of mainline tree, you'll see no such call sites.
All way back to 2008 when kern_path() had been introduced, it had never
been given LOOKUP_PARENT in arguments:

; git log -p -Skern_path | grep ^\+.*\<kern_path\>
+	err = kern_path(mtd_dev, LOOKUP_FOLLOW, &path);
+	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+				ret = kern_path(filename, LOOKUP_FOLLOW, &path);
+	ret = kern_path(pathname->name, LOOKUP_FOLLOW, &path);
+	err = kern_path(name, LOOKUP_FOLLOW, path);
+		error = kern_path(journal_path, LOOKUP_FOLLOW, &path);
+			error = kern_path(journal_path, LOOKUP_FOLLOW, &path);
+		rc = kern_path(name, LOOKUP_FOLLOW, &path);
+	ret = kern_path(filename, LOOKUP_FOLLOW, &path);
+		status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
+static struct ctl_path kern_path[] = { { .procname = "kernel", }, { } };
+	register_sysctl_paths(kern_path, pid_ns_ctl_table);
+		r = kern_path(syspath, LOOKUP_FOLLOW, &path);
+	status = kern_path(recdir, LOOKUP_FOLLOW, &path);
+	/* Drop refcount obtained by kern_path(). */
+	rc = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
+		ecryptfs_printk(KERN_WARNING, "kern_path() failed\n");
+	if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
+		if (kern_path(dev_name, LOOKUP_FOLLOW, &path)) {
+	err = kern_path(mtd_dev, LOOKUP_FOLLOW, &path);
+	ret = kern_path(cache->rootdirname, LOOKUP_DIRECTORY, &path);
+	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	err = kern_path(mountpoint, LOOKUP_FOLLOW, &path);
+	int err = kern_path(pathname, 0, &path);
+			err = kern_path(name, LOOKUP_FOLLOW, &path);
+	error = kern_path(name, LOOKUP_FOLLOW, &path);
+	error = kern_path(dev_name, LOOKUP_FOLLOW, &path);
+	if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
+	if (pathname && kern_path(pathname, LOOKUP_FOLLOW, &path) == 0) {
+	if (pathname && kern_path(pathname, 0, &path) == 0) {
+		err = kern_path(tree->pathname, 0, &path);
+	err = kern_path(tree->pathname, 0, &path);
+	err = kern_path(new, 0, &path);
+	err = kern_path(old, 0, &path);
+		err = kern_path(tree->pathname, 0, &path);
+	error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+	ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path);
+	rc = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
+		err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
+		err = kern_path(buf, 0, &key.ek_path);
+	err = kern_path(nxp->ex_path, 0, &path);
+	err = kern_path(nxp->ex_path, 0, &path);
+	if (kern_path(name, 0, &path)) {
+	status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
+	status = kern_path(recdir, LOOKUP_FOLLOW, &path);
+	error = kern_path(fo_path, 0, &path);
+	err = kern_path(buf, 0, &exp.ex_path);
+	error = kern_path(name, LOOKUP_FOLLOW, &path);
+	err = kern_path(name, LOOKUP_FOLLOW, &path);
+	err = kern_path(name, LOOKUP_FOLLOW, &path);
+	err = kern_path(name, LOOKUP_FOLLOW, &path);
+	err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
+	err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
+	retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
+int kern_path(const char *name, unsigned int flags, struct path *path)
+EXPORT_SYMBOL(kern_path);
+extern int kern_path(const char *, unsigned, struct path *);
;

As you can see, it had only been given LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
LOOKUP_FOLLOW or 0.  Old behaviour in a sense of kern_path() accepting
LOOKUP_PARENT is not going to come back - it would have been inherently racy
all along *and* nothing in mainline kernel had ever attempted that stupidity.

LOOKUP_PARENT had always been only for primitives that had left nameidata
to the caller, so that it could do something about the last component.
kern_path() is nothing of that kind and no, I'm not going to reexpose
nameidata to anything outside of fs/namei.c.

Out of existing primitives kern_path_locked() is the closest sane
approximation.  It could be exported, if your customer cares to give
details.  If they do not, tell them that their abuse of kern_path() accidental
behaviour had been wrong all along and the old versions of their out-of-tree
code are almost certainly racy.  If they are interested in safe replacement,
they'd better provide details.

BTW, see 15a9155fe3e8 (fix race in audit_get_nd()) for an example of similar
race.  That was the one and only bug of that sort that made it into the
mainline.  That was path_lookup() with LOOKUP_PARENT (in principle legitimate)
with nd simply discarded by the caller.

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

* RE: [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag
  2016-10-13 23:31           ` Al Viro
@ 2016-10-14  0:02             ` Remanan Pillai, Vineeth
  0 siblings, 0 replies; 10+ messages in thread
From: Remanan Pillai, Vineeth @ 2016-10-14  0:02 UTC (permalink / raw)
  To: Al Viro
  Cc: Christoph Hellwig, linux-fsdevel, linux-kernel, Kamata, Munehisa,
	Liguori, Anthony

Thanks for the detailed explanation. I understand the reasoning now. 

Thanks, 
Vineeth 
________________________________________
From: Al Viro [viro@ftp.linux.org.uk] on behalf of Al Viro [viro@ZenIV.linux.org.uk]
Sent: Thursday, October 13, 2016 4:31 PM
To: Remanan Pillai, Vineeth
Cc: Christoph Hellwig; linux-fsdevel@vger.kernel.org; linux-kernel@vger.kernel.org; Kamata, Munehisa; Liguori, Anthony
Subject: Re: [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag

On Thu, Oct 13, 2016 at 03:14:23PM -0700, Vineeth Remanan Pillai wrote:
> Unfortunately, I also do not have enough context about the customer
> code that uses it. Since kern_path was exported function and the
> behavior changed across releases, this patch is just trying to revert
> to the old behavior.
> I clearly get what you are trying to say. It would have been really
> beneficial to get the context so as to understand use case and figure out
> alternative or better approach. But I think we should have the functionality
> as before and if kern_path is not the right API for this purpose, probably
> we
> should deprecate it in a phased manner.

kern_path() is not the right API for this purpose.  Never had been.  It is,
OTOH, the right API for other purposes, so it's not going to disappear.
If you check the history of mainline tree, you'll see no such call sites.
All way back to 2008 when kern_path() had been introduced, it had never
been given LOOKUP_PARENT in arguments:

; git log -p -Skern_path | grep ^\+.*\<kern_path\>
+       err = kern_path(mtd_dev, LOOKUP_FOLLOW, &path);
+       error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+                               ret = kern_path(filename, LOOKUP_FOLLOW, &path);
+       ret = kern_path(pathname->name, LOOKUP_FOLLOW, &path);
+       err = kern_path(name, LOOKUP_FOLLOW, path);
+               error = kern_path(journal_path, LOOKUP_FOLLOW, &path);
+                       error = kern_path(journal_path, LOOKUP_FOLLOW, &path);
+               rc = kern_path(name, LOOKUP_FOLLOW, &path);
+       ret = kern_path(filename, LOOKUP_FOLLOW, &path);
+               status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
+static struct ctl_path kern_path[] = { { .procname = "kernel", }, { } };
+       register_sysctl_paths(kern_path, pid_ns_ctl_table);
+               r = kern_path(syspath, LOOKUP_FOLLOW, &path);
+       status = kern_path(recdir, LOOKUP_FOLLOW, &path);
+       /* Drop refcount obtained by kern_path(). */
+       rc = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
+               ecryptfs_printk(KERN_WARNING, "kern_path() failed\n");
+       if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
+               if (kern_path(dev_name, LOOKUP_FOLLOW, &path)) {
+       err = kern_path(mtd_dev, LOOKUP_FOLLOW, &path);
+       ret = kern_path(cache->rootdirname, LOOKUP_DIRECTORY, &path);
+       error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+       err = kern_path(mountpoint, LOOKUP_FOLLOW, &path);
+       int err = kern_path(pathname, 0, &path);
+                       err = kern_path(name, LOOKUP_FOLLOW, &path);
+       error = kern_path(name, LOOKUP_FOLLOW, &path);
+       error = kern_path(dev_name, LOOKUP_FOLLOW, &path);
+       if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
+       if (pathname && kern_path(pathname, LOOKUP_FOLLOW, &path) == 0) {
+       if (pathname && kern_path(pathname, 0, &path) == 0) {
+               err = kern_path(tree->pathname, 0, &path);
+       err = kern_path(tree->pathname, 0, &path);
+       err = kern_path(new, 0, &path);
+       err = kern_path(old, 0, &path);
+               err = kern_path(tree->pathname, 0, &path);
+       error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+       ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path);
+       rc = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
+               err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
+               err = kern_path(buf, 0, &key.ek_path);
+       err = kern_path(nxp->ex_path, 0, &path);
+       err = kern_path(nxp->ex_path, 0, &path);
+       if (kern_path(name, 0, &path)) {
+       status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
+       status = kern_path(recdir, LOOKUP_FOLLOW, &path);
+       error = kern_path(fo_path, 0, &path);
+       err = kern_path(buf, 0, &exp.ex_path);
+       error = kern_path(name, LOOKUP_FOLLOW, &path);
+       err = kern_path(name, LOOKUP_FOLLOW, &path);
+       err = kern_path(name, LOOKUP_FOLLOW, &path);
+       err = kern_path(name, LOOKUP_FOLLOW, &path);
+       err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
+       err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
+       retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
+int kern_path(const char *name, unsigned int flags, struct path *path)
+EXPORT_SYMBOL(kern_path);
+extern int kern_path(const char *, unsigned, struct path *);
;

As you can see, it had only been given LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
LOOKUP_FOLLOW or 0.  Old behaviour in a sense of kern_path() accepting
LOOKUP_PARENT is not going to come back - it would have been inherently racy
all along *and* nothing in mainline kernel had ever attempted that stupidity.

LOOKUP_PARENT had always been only for primitives that had left nameidata
to the caller, so that it could do something about the last component.
kern_path() is nothing of that kind and no, I'm not going to reexpose
nameidata to anything outside of fs/namei.c.

Out of existing primitives kern_path_locked() is the closest sane
approximation.  It could be exported, if your customer cares to give
details.  If they do not, tell them that their abuse of kern_path() accidental
behaviour had been wrong all along and the old versions of their out-of-tree
code are almost certainly racy.  If they are interested in safe replacement,
they'd better provide details.

BTW, see 15a9155fe3e8 (fix race in audit_get_nd()) for an example of similar
race.  That was the one and only bug of that sort that made it into the
mainline.  That was path_lookup() with LOOKUP_PARENT (in principle legitimate)
with nd simply discarded by the caller.

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

end of thread, other threads:[~2016-10-14  0:09 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-13 19:58 [PATCH] namei: revert old behaviour for filename_lookup with LOOKUP_PARENT flag Vineeth Remanan Pillai
2016-10-13 20:06 ` Al Viro
2016-10-13 20:09 ` Christoph Hellwig
2016-10-13 20:26   ` Al Viro
2016-10-13 20:41     ` Vineeth Remanan Pillai
2016-10-13 20:44       ` Christoph Hellwig
2016-10-13 21:24       ` Al Viro
2016-10-13 22:14         ` Vineeth Remanan Pillai
2016-10-13 23:31           ` Al Viro
2016-10-14  0:02             ` Remanan Pillai, Vineeth

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).