LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [BUG]Missing i_sb NULL pointer check in destroy_inode()
       [not found]                   ` <20031109152936.3a9ffb69.akpm@osdl.org>
@ 2003-11-24 19:00                     ` Mingming Cao
  2003-11-24 19:27                       ` Andrew Morton
  2003-11-25  8:36                       ` Christoph Hellwig
  0 siblings, 2 replies; 6+ messages in thread
From: Mingming Cao @ 2003-11-24 19:00 UTC (permalink / raw)
  To: Andrew Morton, linux-kernel, marcelo.tosatti; +Cc: Paul.McKenney

Hello, Andrew, Marcelo,

destroy_inode() dereferences inode->i_sb without checking if it is NULL.
This is inconsistent with its caller: iput() and clear_inode(),  both of
which check inode->i_sb before dereferencing it. Since iput() calls
destroy_inode() after calling file system's .clear_inode method(via
clear_inode()),  some file systems might choose to clear the i_sb in the
.clear_inode super block operation. This results in a crash in
destroy_inode().

This issue exists in both 2.6, 2.4 and 2.4 kernel.  A simple fix against
2.6.0-test9 is included below. 2.4 based fix should be very similar to
this one.  Please take a look and consider include it.  

Many thanks!!

--Mingming
----------------------------------------------------------
diff -urNp linux-2.6.0-test9/fs/inode.c a/fs/inode.c
--- linux-2.6.0-test9/fs/inode.c	2003-10-25 11:44:53.000000000 -0700
+++ a/fs/inode.c	2003-11-20 17:28:04.000000000 -0800
@@ -160,7 +160,7 @@ void destroy_inode(struct inode *inode) 
 	if (inode_has_buffers(inode))
 		BUG();
 	security_inode_free(inode);
-	if (inode->i_sb->s_op->destroy_inode)
+	if (inode->i_sb && inode->i_sb->s_op->destroy_inode)
 		inode->i_sb->s_op->destroy_inode(inode);
 	else
 		kmem_cache_free(inode_cachep, (inode));


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG]Missing i_sb NULL pointer check in destroy_inode()
  2003-11-24 19:00                     ` [BUG]Missing i_sb NULL pointer check in destroy_inode() Mingming Cao
@ 2003-11-24 19:27                       ` Andrew Morton
  2003-11-24 20:10                         ` Mingming Cao
  2003-11-25  8:36                       ` Christoph Hellwig
  1 sibling, 1 reply; 6+ messages in thread
From: Andrew Morton @ 2003-11-24 19:27 UTC (permalink / raw)
  To: Mingming Cao; +Cc: linux-kernel, marcelo.tosatti, Paul.McKenney

Mingming Cao <cmm@us.ibm.com> wrote:
>
> destroy_inode() dereferences inode->i_sb without checking if it is NULL.
> This is inconsistent with its caller: iput() and clear_inode(),  both of
> which check inode->i_sb before dereferencing it.

I assume this has only been observed with an out-of-tree filesystem, but
yes, the consistency is good.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG]Missing i_sb NULL pointer check in destroy_inode()
  2003-11-24 19:27                       ` Andrew Morton
@ 2003-11-24 20:10                         ` Mingming Cao
  0 siblings, 0 replies; 6+ messages in thread
From: Mingming Cao @ 2003-11-24 20:10 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, marcelo.tosatti, Paul.McKenney

On Mon, 2003-11-24 at 11:27, Andrew Morton wrote:
> Mingming Cao <cmm@us.ibm.com> wrote:
> >
> > destroy_inode() dereferences inode->i_sb without checking if it is NULL.
> > This is inconsistent with its caller: iput() and clear_inode(),  both of
> > which check inode->i_sb before dereferencing it.
> 
> I assume this has only been observed with an out-of-tree filesystem, but
> yes, the consistency is good.
> 

Yes,  the crash happened with an out-of-tree filesystem.  Thanks.

-Mingming



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG]Missing i_sb NULL pointer check in destroy_inode()
  2003-11-24 19:00                     ` [BUG]Missing i_sb NULL pointer check in destroy_inode() Mingming Cao
  2003-11-24 19:27                       ` Andrew Morton
@ 2003-11-25  8:36                       ` Christoph Hellwig
  2003-11-26 22:09                         ` Mingming Cao
  1 sibling, 1 reply; 6+ messages in thread
From: Christoph Hellwig @ 2003-11-25  8:36 UTC (permalink / raw)
  To: Mingming Cao; +Cc: Andrew Morton, linux-kernel, marcelo.tosatti, Paul.McKenney

On Mon, Nov 24, 2003 at 11:00:38AM -0800, Mingming Cao wrote:
> Hello, Andrew, Marcelo,
> 
> destroy_inode() dereferences inode->i_sb without checking if it is NULL.
> This is inconsistent with its caller: iput() and clear_inode(),  both of
> which check inode->i_sb before dereferencing it. Since iput() calls
> destroy_inode() after calling file system's .clear_inode method(via
> clear_inode()),  some file systems might choose to clear the i_sb in the
> .clear_inode super block operation. This results in a crash in
> destroy_inode().
> 
> This issue exists in both 2.6, 2.4 and 2.4 kernel.  A simple fix against
> 2.6.0-test9 is included below. 2.4 based fix should be very similar to
> this one.  Please take a look and consider include it.  

inode->i_sb can't be NULL.  We should remove all those checks.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG]Missing i_sb NULL pointer check in destroy_inode()
  2003-11-25  8:36                       ` Christoph Hellwig
@ 2003-11-26 22:09                         ` Mingming Cao
  2003-11-27  1:10                           ` Timo Kamph
  0 siblings, 1 reply; 6+ messages in thread
From: Mingming Cao @ 2003-11-26 22:09 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, linux-kernel, marcelo.tosatti, Paul.McKenney

On Tue, 2003-11-25 at 00:36, Christoph Hellwig wrote:
> On Mon, Nov 24, 2003 at 11:00:38AM -0800, Mingming Cao wrote:
> > Hello, Andrew, Marcelo,
> > 
> > destroy_inode() dereferences inode->i_sb without checking if it is NULL.
> > This is inconsistent with its caller: iput() and clear_inode(),  both of
> > which check inode->i_sb before dereferencing it. Since iput() calls
> > destroy_inode() after calling file system's .clear_inode method(via
> > clear_inode()),  some file systems might choose to clear the i_sb in the
> > .clear_inode super block operation. This results in a crash in
> > destroy_inode().
> > 
> > This issue exists in both 2.6, 2.4 and 2.4 kernel.  A simple fix against
> > 2.6.0-test9 is included below. 2.4 based fix should be very similar to
> > this one.  Please take a look and consider include it.  
> 
> inode->i_sb can't be NULL.  We should remove all those checks.
> 
Sorry I can not agree with this. Maybe the inode->i_sb should not be
NULL, but the kernel still allows the file system to do so.  In fact
JFS's diReadSpecial() function clears the inode->i_sb to NULL before
calling iput().  

Acutally iput() in 2.6 is missing the check too.(in 2.4 the check is
there).  Here is the the incremental fix for 2.6 only:

diff -urNp linux-2.6.0-test10/fs/inode.c a/fs/inode.c
--- linux-2.6.0-test10/fs/inode.c	2003-11-23 17:33:24.000000000 -0800
+++ a/fs/inode.c	2003-11-26 13:59:34.000000000 -0800
@@ -1084,13 +1084,13 @@ static inline void iput_final(struct ino
 void iput(struct inode *inode)
 {
 	if (inode) {
-		struct super_operations *op = inode->i_sb->s_op;
-
+		struct super_block *sb = inode->i_sb;
+		
 		if (inode->i_state == I_CLEAR)
 			BUG();
 
-		if (op && op->put_inode)
-			op->put_inode(inode);
+		if (sb && sb->op && sb->op->put_inode)
+			sb->op->put_inode(inode);
 
 		if (atomic_dec_and_lock(&inode->i_count, &inode_lock))
 			iput_final(inode);





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG]Missing i_sb NULL pointer check in destroy_inode()
  2003-11-26 22:09                         ` Mingming Cao
@ 2003-11-27  1:10                           ` Timo Kamph
  0 siblings, 0 replies; 6+ messages in thread
From: Timo Kamph @ 2003-11-27  1:10 UTC (permalink / raw)
  To: Mingming Cao; +Cc: linux-kernel

On 26 Nov 2003 at 14:09, Mingming Cao wrote:
> On Tue, 2003-11-25 at 00:36, Christoph Hellwig wrote:
> > On Mon, Nov 24, 2003 at 11:00:38AM -0800, Mingming Cao wrote:
> > > Hello, Andrew, Marcelo,
> > > 
> > > destroy_inode() dereferences inode->i_sb without checking if it is NULL.
> > > This is inconsistent with its caller: iput() and clear_inode(),  both of
> > > which check inode->i_sb before dereferencing it. Since iput() calls
> > > destroy_inode() after calling file system's .clear_inode method(via
> > > clear_inode()),  some file systems might choose to clear the i_sb in the
> > > .clear_inode super block operation. This results in a crash in
> > > destroy_inode().
> > > 
> > > This issue exists in both 2.6, 2.4 and 2.4 kernel.  A simple fix against
> > > 2.6.0-test9 is included below. 2.4 based fix should be very similar to
> > > this one.  Please take a look and consider include it.  
> > 
> > inode->i_sb can't be NULL.  We should remove all those checks.
> > 
> Sorry I can not agree with this. Maybe the inode->i_sb should not be
> NULL, but the kernel still allows the file system to do so.  In fact
> JFS's diReadSpecial() function clears the inode->i_sb to NULL before
> calling iput().  
> 
> Acutally iput() in 2.6 is missing the check too.(in 2.4 the check is
> there).  Here is the the incremental fix for 2.6 only:

There is a little typo in your patch. The struct member is s_op and not op.
The following patch should be right.

	Timo

diff -urNp linux-2.6.0-test10/fs/inode.c a/fs/inode.c
--- linux-2.6.0-test10/fs/inode.c	2003-11-23 17:33:24.000000000 -0800
+++ a/fs/inode.c	2003-11-26 13:59:34.000000000 -0800
@@ -1084,13 +1084,13 @@ static inline void iput_final(struct ino
 void iput(struct inode *inode)
 {
 	if (inode) {
-		struct super_operations *op = inode->i_sb->s_op;
-
+		struct super_block *sb = inode->i_sb;
+		
 		if (inode->i_state == I_CLEAR)
 			BUG();
 
-		if (op && op->put_inode)
-			op->put_inode(inode);
+		if (sb && sb->s_op && sb->s_op->put_inode)
+			sb->s_op->put_inode(inode);
 
 		if (atomic_dec_and_lock(&inode->i_count, &inode_lock))
 			iput_final(inode);



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-11-27  1:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1068045518.10730.266.camel@socrates>
     [not found] ` <20031105181600.GC18278@thunk.org>
     [not found]   ` <1068066524.10726.289.camel@socrates>
     [not found]     ` <20031106033817.GB22081@thunk.org>
     [not found]       ` <1068145132.10735.322.camel@socrates>
     [not found]         ` <20031106123922.Y10197@schatzie.adilger.int>
     [not found]           ` <1068148881.10730.337.camel@socrates>
     [not found]             ` <1068230146.10726.359.camel@socrates>
     [not found]               ` <20031109130826.2b37219d.akpm@osdl.org>
     [not found]                 ` <1068419747.687.28.camel@socrates>
     [not found]                   ` <20031109152936.3a9ffb69.akpm@osdl.org>
2003-11-24 19:00                     ` [BUG]Missing i_sb NULL pointer check in destroy_inode() Mingming Cao
2003-11-24 19:27                       ` Andrew Morton
2003-11-24 20:10                         ` Mingming Cao
2003-11-25  8:36                       ` Christoph Hellwig
2003-11-26 22:09                         ` Mingming Cao
2003-11-27  1:10                           ` Timo Kamph

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).