[PATCH] Fix vfs_unlink/NFS NULL pointer dereference
Linux Kernel Mailing List <[email protected]> Wed, 21 Jun 2006 16:59:02 GMT
| Newsgroups | gmane.linux.kernel.commits.2-4 |
|---|---|
| Message-ID | <[email protected]> |
commit 3a1250af4913b54940efaa32ca84d60fcd97990d tree 4609b2df80dee13ff505b54d078deb07ff6667e9 parent 0e978d63375d579260d1eb930f5954f96cd37b7f author Willy Tarreau <[email protected]> Tue, 20 Jun 2006 01:00:07 +0200 committer Marcelo Tosatti <[email protected]> Tue, 20 Jun 2006 17:43:55 -0300 [PATCH] Fix vfs_unlink/NFS NULL pointer dereference v2.4.33-pre introduced a fix for lack of synchronization between link/unlink which requires vfs_unlink to grab i_zombie of both the victim and its parent with double_down(). Problem is that NFS client deletes the victim dentry on ->unlink, resulting in a NULL dereference when vfs_unlink() tries to up dentry->d_inode->i_zombie. Keep a copy of the inode pointer, incrementing its reference counter, to fix the situation. Signed-off-by: Marcelo Tosatti <[email protected]> fs/namei.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 42cce98..374b767 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1478,12 +1478,16 @@ exit: int vfs_unlink(struct inode *dir, struct dentry *dentry) { int error; + struct inode *inode; error = may_delete(dir, dentry, 0); if (error) return error; - double_down(&dir->i_zombie, &dentry->d_inode->i_zombie); + inode = dentry->d_inode; + atomic_inc(&inode->i_count); + double_down(&dir->i_zombie, &inode->i_zombie); + error = -EPERM; if (dir->i_op && dir->i_op->unlink) { DQUOT_INIT(dir); @@ -1495,7 +1499,9 @@ int vfs_unlink(struct inode *dir, struct unlock_kernel(); } } - double_up(&dir->i_zombie, &dentry->d_inode->i_zombie); + double_up(&dir->i_zombie, &inode->i_zombie); + iput(inode); + if (!error) { d_delete(dentry); inode_dir_notify(dir, DN_DELETE);