FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Cluster Development

 
 
LinkBack Thread Tools
 
Old 06-15-2010, 04:07 PM
Bob Peterson
 
Default Fix kernel NULL pointer dereference by dlm_astd

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 <rpeterso@redhat.com>
--
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. */
 
Old 06-17-2010, 08:45 PM
Bob Peterson
 
Default Fix kernel NULL pointer dereference by dlm_astd

Hi,

This patch replaces the one I previously posted here.

Regards,

Bob Peterson
Red Hat File Systems
--
commit 77ac19b0f0061396d0dc15f705ac4e0a574bd614
Author: Bob Peterson <rpeterso@redhat.com>
Date: Thu Jun 17 15:38:32 2010 -0500

GFS2: Fix kernel NULL pointer dereference by dlm_astd

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.

rhbz#604244

diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 4a1f236..21f901f 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -171,7 +171,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
{
struct inode *inode;
struct gfs2_inode *ip;
- struct gfs2_glock *io_gl;
+ struct gfs2_glock *io_gl = NULL;
int error;

inode = gfs2_iget(sb, no_addr);
@@ -200,6 +200,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
ip->i_iopen_gh.gh_gl->gl_object = ip;

gfs2_glock_put(io_gl);
+ io_gl = NULL;

if ((type == DT_UNKNOWN) && (no_formal_ino == 0))
goto gfs2_nfsbypass;
@@ -230,7 +231,8 @@ gfs2_nfsbypass:
fail_glock:
gfs2_glock_dq(&ip->i_iopen_gh);
fail_iopen:
- gfs2_glock_put(io_gl);
+ if (io_gl)
+ gfs2_glock_put(io_gl);
fail_put:
if (inode->i_state & I_NEW)
ip->i_gl->gl_object = NULL;
@@ -258,7 +260,7 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)
{
struct gfs2_sbd *sdp;
struct gfs2_inode *ip;
- struct gfs2_glock *io_gl;
+ struct gfs2_glock *io_gl = NULL;
int error;
struct gfs2_holder gh;
struct inode *inode;
@@ -295,6 +297,7 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)

ip->i_iopen_gh.gh_gl->gl_object = ip;
gfs2_glock_put(io_gl);
+ io_gl = NULL;

inode->i_mode = DT2IF(DT_UNKNOWN);

@@ -321,7 +324,8 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)
fail_glock:
gfs2_glock_dq(&ip->i_iopen_gh);
fail_iopen:
- gfs2_glock_put(io_gl);
+ if (io_gl)
+ gfs2_glock_put(io_gl);
fail_put:
ip->i_gl->gl_object = NULL;
gfs2_glock_put(ip->i_gl);
 

Thread Tools




All times are GMT. The time now is 06:00 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org