From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bob Peterson Date: Tue, 15 Jun 2010 12:07:19 -0400 (EDT) Subject: [Cluster-devel] [PATCH GFS2] Fix kernel NULL pointer dereference by dlm_astd In-Reply-To: <1012171873.203921276617969511.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> Message-ID: <1053462697.204231276618039475.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi, This patch fixes a problem in an error path when looking up dinodes. There are two sister-functions, gfs2_inode_lookup and gfs2_process_unlinked_inode. Both functions acquire and hold the i_iopen glock for the dinode being looked up. The last thing they try to do is hold the i_gl glock for the dinode. If that glock fails for some reason, the error path was incorrectly calling gfs2_glock_put for the i_iopen glock twice. This resulted in the glock being prematurely freed. The "minimum hold time" usually kept the glock in memory, but the lock interface to dlm (aka lock_dlm) freed its memory for the glock. In some circumstances, it would cause dlm's dlm_astd daemon to try to call the bast function for the freed lock_dlm memory, which resulted in a NULL pointer dereference. This problem was discovered while testing bugzilla bug #595397. Regards, Bob Peterson Red Hat GFS Signed-off-by: Bob Peterson -- fs/gfs2/inode.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index b5612cb..43e06ff 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -197,8 +197,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, goto fail_iopen; ip->i_iopen_gh.gh_gl->gl_object = ip; - gfs2_glock_put(io_gl); - if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) goto gfs2_nfsbypass; @@ -224,6 +222,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, } gfs2_nfsbypass: + gfs2_glock_put(io_gl); + return inode; fail_glock: gfs2_glock_dq(&ip->i_iopen_gh); @@ -292,7 +292,6 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr) goto fail_iopen; ip->i_iopen_gh.gh_gl->gl_object = ip; - gfs2_glock_put(io_gl); inode->i_mode = DT2IF(DT_UNKNOWN); @@ -310,6 +309,7 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr) /* Inode is now uptodate */ gfs2_glock_dq_uninit(&gh); + gfs2_glock_put(io_gl); gfs2_set_iop(inode); /* The iput will cause it to be deleted. */