* [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.