All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] vfs: check value of varaiable 'nd' before using its member
@ 2012-07-04  9:32 Robin Dong
  2012-07-04  9:39 ` Steven Whitehouse
  0 siblings, 1 reply; 4+ messages in thread
From: Robin Dong @ 2012-07-04  9:32 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: Robin Dong

From: Robin Dong <sanbai@taobao.com>

When we using lookup_one_len() to search pathname component, it will call __lookup_hash()
with variable 'nd' as NULL :

	--> __lookup_hash ( nd = NULL )
		--> lookup_dcache
			--> d_invalidate
				--> proc_sys_revalidate

the proc_sys_revalidate will use 'nd->flags' before check whether its value is NULL.
This will cause kernel panic.

Therefore, we should adding check-code for filesystems which directly use nd->flags.

Signed-off-by: Robin Dong <sanbai@taobao.com>
---
 fs/9p/vfs_dentry.c    |    2 +-
 fs/afs/dir.c          |    2 +-
 fs/coda/dir.c         |    2 +-
 fs/hfs/sysdep.c       |    2 +-
 fs/ncpfs/dir.c        |    2 +-
 fs/nfs/dir.c          |    2 +-
 fs/proc/proc_sysctl.c |    2 +-
 fs/sysfs/dir.c        |    2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index d529437..2785900 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -106,7 +106,7 @@ static int v9fs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd)
 	struct inode *inode;
 	struct v9fs_inode *v9inode;
 
-	if (nd->flags & LOOKUP_RCU)
+	if (nd && nd->flags & LOOKUP_RCU)
 		return -ECHILD;
 
 	inode = dentry->d_inode;
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index e22dc4b..93c1bbb 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -607,7 +607,7 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
 	void *dir_version;
 	int ret;
 
-	if (nd->flags & LOOKUP_RCU)
+	if (nd && nd->flags & LOOKUP_RCU)
 		return -ECHILD;
 
 	vnode = AFS_FS_I(dentry->d_inode);
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 1775158..804344d 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -541,7 +541,7 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
 	struct inode *inode;
 	struct coda_inode_info *cii;
 
-	if (nd->flags & LOOKUP_RCU)
+	if (nd && nd->flags & LOOKUP_RCU)
 		return -ECHILD;
 
 	inode = de->d_inode;
diff --git a/fs/hfs/sysdep.c b/fs/hfs/sysdep.c
index 19cf291..1127ea3 100644
--- a/fs/hfs/sysdep.c
+++ b/fs/hfs/sysdep.c
@@ -18,7 +18,7 @@ static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata *nd)
 	struct inode *inode;
 	int diff;
 
-	if (nd->flags & LOOKUP_RCU)
+	if (nd && nd->flags & LOOKUP_RCU)
 		return -ECHILD;
 
 	inode = dentry->d_inode;
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index aeed93a..69d6b55 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -302,7 +302,7 @@ ncp_lookup_validate(struct dentry *dentry, struct nameidata *nd)
 	if (dentry == dentry->d_sb->s_root)
 		return 1;
 
-	if (nd->flags & LOOKUP_RCU)
+	if (nd && nd->flags & LOOKUP_RCU)
 		return -ECHILD;
 
 	parent = dget_parent(dentry);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index f430057..badda4e 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1123,7 +1123,7 @@ static int nfs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd)
 	struct nfs_fattr *fattr = NULL;
 	int error;
 
-	if (nd->flags & LOOKUP_RCU)
+	if (nd && nd->flags & LOOKUP_RCU)
 		return -ECHILD;
 
 	parent = dget_parent(dentry);
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 3476bca..7df97f5 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -796,7 +796,7 @@ static const struct inode_operations proc_sys_dir_operations = {
 
 static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
-	if (nd->flags & LOOKUP_RCU)
+	if (nd && nd->flags & LOOKUP_RCU)
 		return -ECHILD;
 	return !PROC_I(dentry->d_inode)->sysctl->unregistering;
 }
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index e6bb9b2..9f02776 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -308,7 +308,7 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, struct nameidata *nd)
 	struct sysfs_dirent *sd;
 	int is_dir;
 
-	if (nd->flags & LOOKUP_RCU)
+	if (nd && nd->flags & LOOKUP_RCU)
 		return -ECHILD;
 
 	sd = dentry->d_fsdata;
-- 
1.7.3.2


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

* Re: [PATCH] vfs: check value of varaiable 'nd' before using its member
  2012-07-04  9:32 [PATCH] vfs: check value of varaiable 'nd' before using its member Robin Dong
@ 2012-07-04  9:39 ` Steven Whitehouse
  2012-07-04 18:30   ` Al Viro
  0 siblings, 1 reply; 4+ messages in thread
From: Steven Whitehouse @ 2012-07-04  9:39 UTC (permalink / raw)
  To: Robin Dong; +Cc: linux-fsdevel, Robin Dong

Hi,

On Wed, 2012-07-04 at 17:32 +0800, Robin Dong wrote:
> From: Robin Dong <sanbai@taobao.com>
> 
> When we using lookup_one_len() to search pathname component, it will call __lookup_hash()
> with variable 'nd' as NULL :
> 
> 	--> __lookup_hash ( nd = NULL )
> 		--> lookup_dcache
> 			--> d_invalidate
> 				--> proc_sys_revalidate
> 
> the proc_sys_revalidate will use 'nd->flags' before check whether its value is NULL.
> This will cause kernel panic.
> 
> Therefore, we should adding check-code for filesystems which directly use nd->flags.
> 
> Signed-off-by: Robin Dong <sanbai@taobao.com>

nd will very shortly no longer be passed to revalidate... see this patch
in Al's vfs git tree:

http://git.kernel.org/?p=linux/kernel/git/viro/vfs.git;a=commitdiff;h=282638cce7050592b3d6267ae08ea2573908998c#patch4

Steve.

> ---
>  fs/9p/vfs_dentry.c    |    2 +-
>  fs/afs/dir.c          |    2 +-
>  fs/coda/dir.c         |    2 +-
>  fs/hfs/sysdep.c       |    2 +-
>  fs/ncpfs/dir.c        |    2 +-
>  fs/nfs/dir.c          |    2 +-
>  fs/proc/proc_sysctl.c |    2 +-
>  fs/sysfs/dir.c        |    2 +-
>  8 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
> index d529437..2785900 100644
> --- a/fs/9p/vfs_dentry.c
> +++ b/fs/9p/vfs_dentry.c
> @@ -106,7 +106,7 @@ static int v9fs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd)
>  	struct inode *inode;
>  	struct v9fs_inode *v9inode;
>  
> -	if (nd->flags & LOOKUP_RCU)
> +	if (nd && nd->flags & LOOKUP_RCU)
>  		return -ECHILD;
>  
>  	inode = dentry->d_inode;
> diff --git a/fs/afs/dir.c b/fs/afs/dir.c
> index e22dc4b..93c1bbb 100644
> --- a/fs/afs/dir.c
> +++ b/fs/afs/dir.c
> @@ -607,7 +607,7 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
>  	void *dir_version;
>  	int ret;
>  
> -	if (nd->flags & LOOKUP_RCU)
> +	if (nd && nd->flags & LOOKUP_RCU)
>  		return -ECHILD;
>  
>  	vnode = AFS_FS_I(dentry->d_inode);
> diff --git a/fs/coda/dir.c b/fs/coda/dir.c
> index 1775158..804344d 100644
> --- a/fs/coda/dir.c
> +++ b/fs/coda/dir.c
> @@ -541,7 +541,7 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
>  	struct inode *inode;
>  	struct coda_inode_info *cii;
>  
> -	if (nd->flags & LOOKUP_RCU)
> +	if (nd && nd->flags & LOOKUP_RCU)
>  		return -ECHILD;
>  
>  	inode = de->d_inode;
> diff --git a/fs/hfs/sysdep.c b/fs/hfs/sysdep.c
> index 19cf291..1127ea3 100644
> --- a/fs/hfs/sysdep.c
> +++ b/fs/hfs/sysdep.c
> @@ -18,7 +18,7 @@ static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata *nd)
>  	struct inode *inode;
>  	int diff;
>  
> -	if (nd->flags & LOOKUP_RCU)
> +	if (nd && nd->flags & LOOKUP_RCU)
>  		return -ECHILD;
>  
>  	inode = dentry->d_inode;
> diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
> index aeed93a..69d6b55 100644
> --- a/fs/ncpfs/dir.c
> +++ b/fs/ncpfs/dir.c
> @@ -302,7 +302,7 @@ ncp_lookup_validate(struct dentry *dentry, struct nameidata *nd)
>  	if (dentry == dentry->d_sb->s_root)
>  		return 1;
>  
> -	if (nd->flags & LOOKUP_RCU)
> +	if (nd && nd->flags & LOOKUP_RCU)
>  		return -ECHILD;
>  
>  	parent = dget_parent(dentry);
> diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
> index f430057..badda4e 100644
> --- a/fs/nfs/dir.c
> +++ b/fs/nfs/dir.c
> @@ -1123,7 +1123,7 @@ static int nfs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd)
>  	struct nfs_fattr *fattr = NULL;
>  	int error;
>  
> -	if (nd->flags & LOOKUP_RCU)
> +	if (nd && nd->flags & LOOKUP_RCU)
>  		return -ECHILD;
>  
>  	parent = dget_parent(dentry);
> diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
> index 3476bca..7df97f5 100644
> --- a/fs/proc/proc_sysctl.c
> +++ b/fs/proc/proc_sysctl.c
> @@ -796,7 +796,7 @@ static const struct inode_operations proc_sys_dir_operations = {
>  
>  static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
>  {
> -	if (nd->flags & LOOKUP_RCU)
> +	if (nd && nd->flags & LOOKUP_RCU)
>  		return -ECHILD;
>  	return !PROC_I(dentry->d_inode)->sysctl->unregistering;
>  }
> diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
> index e6bb9b2..9f02776 100644
> --- a/fs/sysfs/dir.c
> +++ b/fs/sysfs/dir.c
> @@ -308,7 +308,7 @@ static int sysfs_dentry_revalidate(struct dentry *dentry, struct nameidata *nd)
>  	struct sysfs_dirent *sd;
>  	int is_dir;
>  
> -	if (nd->flags & LOOKUP_RCU)
> +	if (nd && nd->flags & LOOKUP_RCU)
>  		return -ECHILD;
>  
>  	sd = dentry->d_fsdata;
> -- 
> 1.7.3.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



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

* Re: [PATCH] vfs: check value of varaiable 'nd' before using its member
  2012-07-04  9:39 ` Steven Whitehouse
@ 2012-07-04 18:30   ` Al Viro
  2012-07-05  2:22     ` Dong Robin
  0 siblings, 1 reply; 4+ messages in thread
From: Al Viro @ 2012-07-04 18:30 UTC (permalink / raw)
  To: Steven Whitehouse; +Cc: Robin Dong, linux-fsdevel, Robin Dong

On Wed, Jul 04, 2012 at 10:39:09AM +0100, Steven Whitehouse wrote:
> Hi,
> 
> On Wed, 2012-07-04 at 17:32 +0800, Robin Dong wrote:
> > From: Robin Dong <sanbai@taobao.com>
> > 
> > When we using lookup_one_len() to search pathname component, it will call __lookup_hash()
> > with variable 'nd' as NULL :
> > 
> > 	--> __lookup_hash ( nd = NULL )
> > 		--> lookup_dcache
> > 			--> d_invalidate
> > 				--> proc_sys_revalidate
> > 
> > the proc_sys_revalidate will use 'nd->flags' before check whether its value is NULL.
> > This will cause kernel panic.
> > 
> > Therefore, we should adding check-code for filesystems which directly use nd->flags.
> > 
> > Signed-off-by: Robin Dong <sanbai@taobao.com>
> 
> nd will very shortly no longer be passed to revalidate... see this patch
> in Al's vfs git tree:
> 

Not to mention that anyone who tries to export procfs over nfs deserves Bad Things(tm)
happening to them....

IOW, what the hell is your code trying to do?

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

* Re: [PATCH] vfs: check value of varaiable 'nd' before using its member
  2012-07-04 18:30   ` Al Viro
@ 2012-07-05  2:22     ` Dong Robin
  0 siblings, 0 replies; 4+ messages in thread
From: Dong Robin @ 2012-07-05  2:22 UTC (permalink / raw)
  To: Al Viro; +Cc: Steven Whitehouse, linux-fsdevel, Robin Dong

2012/7/5 Al Viro <viro@zeniv.linux.org.uk>:
> On Wed, Jul 04, 2012 at 10:39:09AM +0100, Steven Whitehouse wrote:
>> Hi,
>>
>> On Wed, 2012-07-04 at 17:32 +0800, Robin Dong wrote:
>> > From: Robin Dong <sanbai@taobao.com>
>> >
>> > When we using lookup_one_len() to search pathname component, it will call __lookup_hash()
>> > with variable 'nd' as NULL :
>> >
>> >     --> __lookup_hash ( nd = NULL )
>> >             --> lookup_dcache
>> >                     --> d_invalidate
>> >                             --> proc_sys_revalidate
>> >
>> > the proc_sys_revalidate will use 'nd->flags' before check whether its value is NULL.
>> > This will cause kernel panic.
>> >
>> > Therefore, we should adding check-code for filesystems which directly use nd->flags.
>> >
>> > Signed-off-by: Robin Dong <sanbai@taobao.com>
>>
>> nd will very shortly no longer be passed to revalidate... see this patch
>> in Al's vfs git tree:
>>
>
> Not to mention that anyone who tries to export procfs over nfs deserves Bad Things(tm)
> happening to them....
>
> IOW, what the hell is your code trying to do?

I have found kernel panic on proc_sys_revalidate for using 'nd->flags'
with value of 'nd' as NULL when testing overlayfs.
I haven't seen the patch
(http://git.kernel.org/?p=linux/kernel/git/viro/vfs.git;a=commitdiff;h=282638cce7050592b3d6267ae08ea2573908998c#patch4)
before, so....
Sorry for disturbing you.

-- 
--
Best Regard
Robin Dong

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

end of thread, other threads:[~2012-07-05  2:22 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-04  9:32 [PATCH] vfs: check value of varaiable 'nd' before using its member Robin Dong
2012-07-04  9:39 ` Steven Whitehouse
2012-07-04 18:30   ` Al Viro
2012-07-05  2:22     ` Dong Robin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.