* [PATCH] NFS: possible NULL pointer deref in nfs_sillyrename()
@ 2006-08-16 22:22 Jesper Juhl
2006-08-17 0:16 ` Trond Myklebust
0 siblings, 1 reply; 4+ messages in thread
From: Jesper Juhl @ 2006-08-16 22:22 UTC (permalink / raw)
To: linux-kernel; +Cc: Rick Sladkey, Olaf Kirch, Neil Brown, Trond Myklebust, nfs
The coverity checker spotted this as bug #1013.
If we get a NULL dentry->d_inode, then regardless of
NFS_PARANOIA or no NFS_PARANOIA, then if
if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
turns out to be false we'll end up dereferencing
that NULL d_inode in two places below.
And since the check for "(!dentry->d_inode)" even exists
(although inside #ifdef NFS_PARANOIA) I take that to mean
that this is a possibility.
And the fact that we check
if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
must also mean that there are cases where the check could
fail.
So, we can get in trouble here :
1) as an arg to sprintf() :
sprintf(silly, ".nfs%*.*lx",
i_inosize, i_inosize, dentry->d_inode->i_ino);
2) or we pass it to nfs_inode_return_delegation() which then dereferences it.
nfs_inode_return_delegation(dentry->d_inode);
I propose the following patch to handle this.
Compile tested only.
If this patch is somehow incorrect I'd appreciate an explanation of why :)
Signed-off-by: Jesper Juhl <jesper.juhl@gmail.com>
---
fs/nfs/dir.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
--- linux-2.6.18-rc4-orig/fs/nfs/dir.c 2006-08-11 00:11:12.000000000 +0200
+++ linux-2.6.18-rc4/fs/nfs/dir.c 2006-08-17 00:06:23.000000000 +0200
@@ -1299,15 +1299,15 @@ static int nfs_sillyrename(struct inode
atomic_read(&dentry->d_count));
nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
-#ifdef NFS_PARANOIA
-if (!dentry->d_inode)
-printk("NFS: silly-renaming %s/%s, negative dentry??\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
+ error = -EBUSY;
+ if (!dentry->d_inode) {
+ printk("NFS: silly-renaming %s/%s, negative dentry??\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name);
+ goto out;
+ }
/*
* We don't allow a dentry to be silly-renamed twice.
*/
- error = -EBUSY;
if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
goto out;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] NFS: possible NULL pointer deref in nfs_sillyrename()
2006-08-16 22:22 [PATCH] NFS: possible NULL pointer deref in nfs_sillyrename() Jesper Juhl
@ 2006-08-17 0:16 ` Trond Myklebust
2006-08-17 10:05 ` Jesper Juhl
0 siblings, 1 reply; 4+ messages in thread
From: Trond Myklebust @ 2006-08-17 0:16 UTC (permalink / raw)
To: Jesper Juhl; +Cc: linux-kernel, Rick Sladkey, Neil Brown, nfs
On Thu, 2006-08-17 at 00:22 +0200, Jesper Juhl wrote:
> The coverity checker spotted this as bug #1013.
>
> If we get a NULL dentry->d_inode, then regardless of
> NFS_PARANOIA or no NFS_PARANOIA, then if
> if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
> turns out to be false we'll end up dereferencing
> that NULL d_inode in two places below.
>
> And since the check for "(!dentry->d_inode)" even exists
> (although inside #ifdef NFS_PARANOIA) I take that to mean
> that this is a possibility.
Sorry, but it isn't possible. See the checks in may_delete() (which is
called before ->unlink()) and nfs_rename().
IOW: Feel free to kill the NFS_PARANOIA crap. It looks like legacy code
from a debugging session about a decade or so ago.
Cheers,
Trond
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] NFS: possible NULL pointer deref in nfs_sillyrename()
2006-08-17 0:16 ` Trond Myklebust
@ 2006-08-17 10:05 ` Jesper Juhl
2006-09-19 0:25 ` Kill NFS_PARANOIA (was: Re: [PATCH] NFS: possible NULL pointer deref in nfs_sillyrename() ) Jesper Juhl
0 siblings, 1 reply; 4+ messages in thread
From: Jesper Juhl @ 2006-08-17 10:05 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-kernel, Rick Sladkey, Neil Brown, nfs
On 17/08/06, Trond Myklebust <trond.myklebust@fys.uio.no> wrote:
> On Thu, 2006-08-17 at 00:22 +0200, Jesper Juhl wrote:
> > The coverity checker spotted this as bug #1013.
> >
> > If we get a NULL dentry->d_inode, then regardless of
> > NFS_PARANOIA or no NFS_PARANOIA, then if
> > if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
> > turns out to be false we'll end up dereferencing
> > that NULL d_inode in two places below.
> >
> > And since the check for "(!dentry->d_inode)" even exists
> > (although inside #ifdef NFS_PARANOIA) I take that to mean
> > that this is a possibility.
>
> Sorry, but it isn't possible. See the checks in may_delete() (which is
> called before ->unlink()) and nfs_rename().
>
Thanks, that was useful info.
> IOW: Feel free to kill the NFS_PARANOIA crap. It looks like legacy code
> from a debugging session about a decade or so ago.
>
Sure thing, I'll cook up a patch to do that.
--
Jesper Juhl <jesper.juhl@gmail.com>
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
Plain text mails only, please http://www.expita.com/nomime.html
^ permalink raw reply [flat|nested] 4+ messages in thread
* Kill NFS_PARANOIA (was: Re: [PATCH] NFS: possible NULL pointer deref in nfs_sillyrename() )
2006-08-17 10:05 ` Jesper Juhl
@ 2006-09-19 0:25 ` Jesper Juhl
0 siblings, 0 replies; 4+ messages in thread
From: Jesper Juhl @ 2006-09-19 0:25 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-kernel, Rick Sladkey, Neil Brown, nfs, Jesper Juhl
On Thursday 17 August 2006 12:05, Jesper Juhl wrote:
> On 17/08/06, Trond Myklebust <trond.myklebust@fys.uio.no> wrote:
[...]
>
> > IOW: Feel free to kill the NFS_PARANOIA crap. It looks like legacy code
> > from a debugging session about a decade or so ago.
> >
> Sure thing, I'll cook up a patch to do that.
>
How about something like this:
Remove obsolete NFS_PARANOIA
Signed-off-by: Jesper Juhl <jesper.juhl@gmail.com>
---
fs/nfs/dir.c | 22 ++--------------------
fs/nfs/inode.c | 11 +----------
fs/nfs/nfs2xdr.c | 1 -
fs/nfs/pagelist.c | 7 ++-----
4 files changed, 5 insertions(+), 36 deletions(-)
diff -upr linux-2.6.18-rc7-git2-orig/fs/nfs/dir.c linux-2.6.18-rc7-git2/fs/nfs/dir.c
--- linux-2.6.18-rc7-git2-orig/fs/nfs/dir.c 2006-09-14 13:08:55.000000000 +0200
+++ linux-2.6.18-rc7-git2/fs/nfs/dir.c 2006-09-19 01:35:02.000000000 +0200
@@ -36,7 +36,6 @@
#include "delegation.h"
#include "iostat.h"
-#define NFS_PARANOIA 1
/* #define NFS_DEBUG_VERBOSE 1 */
static int nfs_opendir(struct inode *, struct file *);
@@ -1299,11 +1298,7 @@ static int nfs_sillyrename(struct inode
atomic_read(&dentry->d_count));
nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
-#ifdef NFS_PARANOIA
-if (!dentry->d_inode)
-printk("NFS: silly-renaming %s/%s, negative dentry??\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
+ BUG_ON(!dentry->d_inode);
/*
* We don't allow a dentry to be silly-renamed twice.
*/
@@ -1452,11 +1447,6 @@ nfs_symlink(struct inode *dir, struct de
dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s)\n", dir->i_sb->s_id,
dir->i_ino, dentry->d_name.name, symname);
-#ifdef NFS_PARANOIA
-if (dentry->d_inode)
-printk("nfs_proc_symlink: %s/%s not negative!\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
/*
* Fill in the sattr for the call.
* Note: SunOS 4.1.2 crashes if the mode isn't initialized!
@@ -1584,16 +1574,8 @@ static int nfs_rename(struct inode *old_
new_inode = NULL;
/* instantiate the replacement target */
d_instantiate(new_dentry, NULL);
- } else if (atomic_read(&new_dentry->d_count) > 1) {
- /* dentry still busy? */
-#ifdef NFS_PARANOIA
- printk("nfs_rename: target %s/%s busy, d_count=%d\n",
- new_dentry->d_parent->d_name.name,
- new_dentry->d_name.name,
- atomic_read(&new_dentry->d_count));
-#endif
+ } else if (atomic_read(&new_dentry->d_count) > 1)
goto out;
- }
} else
new_inode->i_nlink--;
diff -upr linux-2.6.18-rc7-git2-orig/fs/nfs/inode.c linux-2.6.18-rc7-git2/fs/nfs/inode.c
--- linux-2.6.18-rc7-git2-orig/fs/nfs/inode.c 2006-09-14 13:08:55.000000000 +0200
+++ linux-2.6.18-rc7-git2/fs/nfs/inode.c 2006-09-19 01:37:10.000000000 +0200
@@ -48,7 +48,6 @@
#include "internal.h"
#define NFSDBG_FACILITY NFSDBG_VFS
-#define NFS_PARANOIA 1
static void nfs_invalidate_inode(struct inode *);
static int nfs_update_inode(struct inode *, struct nfs_fattr *);
@@ -895,7 +894,7 @@ static int nfs_update_inode(struct inode
* Make sure the inode's type hasn't changed.
*/
if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
- goto out_changed;
+ goto out_err;
server = NFS_SERVER(inode);
/* Update the fsid if and only if this is the root directory */
@@ -1005,14 +1004,6 @@ static int nfs_update_inode(struct inode
nfsi->cache_validity |= invalid;
return 0;
- out_changed:
- /*
- * Big trouble! The inode has become a different object.
- */
-#ifdef NFS_PARANOIA
- printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n",
- __FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode);
-#endif
out_err:
/*
* No need to worry about unhashing the dentry, as the
diff -upr linux-2.6.18-rc7-git2-orig/fs/nfs/nfs2xdr.c linux-2.6.18-rc7-git2/fs/nfs/nfs2xdr.c
--- linux-2.6.18-rc7-git2-orig/fs/nfs/nfs2xdr.c 2006-09-14 13:08:55.000000000 +0200
+++ linux-2.6.18-rc7-git2/fs/nfs/nfs2xdr.c 2006-09-19 01:37:31.000000000 +0200
@@ -26,7 +26,6 @@
#include "internal.h"
#define NFSDBG_FACILITY NFSDBG_XDR
-/* #define NFS_PARANOIA 1 */
/* Mapping from NFS error code to "errno" error code. */
#define errno_NFSERR_IO EIO
diff -upr linux-2.6.18-rc7-git2-orig/fs/nfs/pagelist.c linux-2.6.18-rc7-git2/fs/nfs/pagelist.c
--- linux-2.6.18-rc7-git2-orig/fs/nfs/pagelist.c 2006-09-14 13:08:55.000000000 +0200
+++ linux-2.6.18-rc7-git2/fs/nfs/pagelist.c 2006-09-19 01:38:28.000000000 +0200
@@ -18,7 +18,6 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
-#define NFS_PARANOIA 1
static kmem_cache_t *nfs_page_cachep;
@@ -171,10 +170,8 @@ nfs_release_request(struct nfs_page *req
if (!atomic_dec_and_test(&req->wb_count))
return;
-#ifdef NFS_PARANOIA
- BUG_ON (!list_empty(&req->wb_list));
- BUG_ON (NFS_WBACK_BUSY(req));
-#endif
+ BUG_ON(!list_empty(&req->wb_list));
+ BUG_ON(NFS_WBACK_BUSY(req));
/* Release struct file or cached credential */
nfs_clear_request(req);
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2006-09-19 0:25 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-16 22:22 [PATCH] NFS: possible NULL pointer deref in nfs_sillyrename() Jesper Juhl
2006-08-17 0:16 ` Trond Myklebust
2006-08-17 10:05 ` Jesper Juhl
2006-09-19 0:25 ` Kill NFS_PARANOIA (was: Re: [PATCH] NFS: possible NULL pointer deref in nfs_sillyrename() ) Jesper Juhl
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox