From: Robin Dong <sanbai@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html