* [PATCH] ocfs2: dereference before NULL check in ocfs2_direct_IO_get_blocks()
@ 2006-06-03 15:34 Florin Malita
2006-06-03 19:15 ` Alexey Dobriyan
0 siblings, 1 reply; 6+ messages in thread
From: Florin Malita @ 2006-06-03 15:34 UTC (permalink / raw)
To: mark.fasheh, kurt.hackel; +Cc: linux-kernel, akpm
'bh_result' & 'inode' are explicitly checked against NULL so they
shouldn't be dereferenced prior to that.
Coverity ID: 1273, 1274.
Signed-off-by: Florin Malita <fmalita@gmail.com>
---
fs/ocfs2/aops.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 47152bf..16d6478 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -559,13 +559,14 @@ static int ocfs2_direct_IO_get_blocks(st
u64 p_blkno;
int contig_blocks;
unsigned char blocksize_bits;
- unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
+ unsigned long max_blocks;
if (!inode || !bh_result) {
mlog(ML_ERROR, "inode or bh_result is null\n");
return -EIO;
}
+ max_blocks = bh_result->b_size >> inode->i_blkbits;
blocksize_bits = inode->i_sb->s_blocksize_bits;
/* This function won't even be called if the request isn't all
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] ocfs2: dereference before NULL check in ocfs2_direct_IO_get_blocks()
2006-06-03 15:34 [PATCH] ocfs2: dereference before NULL check in ocfs2_direct_IO_get_blocks() Florin Malita
@ 2006-06-03 19:15 ` Alexey Dobriyan
2006-06-03 21:16 ` Joel Becker
2006-06-03 23:30 ` Florin Malita
0 siblings, 2 replies; 6+ messages in thread
From: Alexey Dobriyan @ 2006-06-03 19:15 UTC (permalink / raw)
To: Florin Malita; +Cc: mark.fasheh, kurt.hackel, linux-kernel, akpm
On Sat, Jun 03, 2006 at 11:34:39AM -0400, Florin Malita wrote:
> 'bh_result' & 'inode' are explicitly checked against NULL so they
> shouldn't be dereferenced prior to that.
>
> Coverity ID: 1273, 1274.
> --- a/fs/ocfs2/aops.c
> +++ b/fs/ocfs2/aops.c
> @@ -559,13 +559,14 @@ static int ocfs2_direct_IO_get_blocks(st
> u64 p_blkno;
> int contig_blocks;
> unsigned char blocksize_bits;
> - unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
> + unsigned long max_blocks;
>
> if (!inode || !bh_result) {
> mlog(ML_ERROR, "inode or bh_result is null\n");
> return -EIO;
> }
>
> + max_blocks = bh_result->b_size >> inode->i_blkbits;
> blocksize_bits = inode->i_sb->s_blocksize_bits;
AFAICS, the patch is BS, as usual with this type of patches.
Can "inode" and "bh_result" be NULL here? I bet they can't.
1. The sole purpose of ocfs2_direct_IO_get_blocks() is to be given to
blockdev_direct_IO_no_locking() at fs/ocfs2/aops.c:662
Can blockdev_direct_IO_no_locking() call it with first or third
arg being NULL?
2. blockdev_direct_IO_no_locking() is static inline wrapper
include/linux/fs.h:1687
Can __blockdev_direct_IO() call it's "get_block" arg with first
or third arg being NULL?
3. Aiee, __blockdev_direct_IO() is normal function (fs/direct-io.c:1179)
and it gives damn "get_block" arg to direct_io_worker() at
fs/direct-io.c:1276
4. direct_io_worker() initializes ->get_block method of "dio" structure
and then does something my tiny mind fails to understand. All I can
see it doesn't call nor change method later.
Where is ->get_block called?
5. That what grep(1) is for. One place
fs/direct-io.c:553: ret = (*dio->get_block)(dio->inode, fs_startblk,
fs/direct-io.c-554- map_bh, create);
Now time to press PageUp. We're seeking for dereferences of
"dio->inode" and "map_bh" above.
6. Both are immediately out of question:
536 map_bh->b_size = fs_count << dio->inode->i_blkbits;
^^^^^^ ^^^^^^^^^^
so it can't be NULL ditto
537
538 create = dio->rw == WRITE;
539 if (dio->lock_type == DIO_LOCKING) {
540 if (dio->block_in_file < (i_size_read(dio->inode) >>
541 dio->blkbits))
542 create = 0;
543 } else if (dio->lock_type == DIO_NO_LOCKING) {
544 create = 0;
545 }
546
547 /*
548 * For writes inside i_size we forbid block creations: only
549 * overwrites are permitted. We fall back to buffered writes
550 * at a higher level for inside-i_size block-instantiating
551 * writes.
552 */
553 ret = (*dio->get_block)(dio->inode, fs_startblk,
^^^^^^^^^^^^^^ ^^^^^^^^^^
offending call offending arg
554 map_bh, create);
^^^^^^
offending arg
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ocfs2: dereference before NULL check in ocfs2_direct_IO_get_blocks()
2006-06-03 19:15 ` Alexey Dobriyan
@ 2006-06-03 21:16 ` Joel Becker
2006-06-04 9:15 ` Arjan van de Ven
2006-06-03 23:30 ` Florin Malita
1 sibling, 1 reply; 6+ messages in thread
From: Joel Becker @ 2006-06-03 21:16 UTC (permalink / raw)
To: Alexey Dobriyan
Cc: Florin Malita, mark.fasheh, kurt.hackel, linux-kernel, akpm
On Sat, Jun 03, 2006 at 11:15:58PM +0400, Alexey Dobriyan wrote:
> On Sat, Jun 03, 2006 at 11:34:39AM -0400, Florin Malita wrote:
> > 'bh_result' & 'inode' are explicitly checked against NULL so they
> > shouldn't be dereferenced prior to that.
> >
> > Coverity ID: 1273, 1274.
>
> AFAICS, the patch is BS, as usual with this type of patches.
>
> Can "inode" and "bh_result" be NULL here? I bet they can't.
This is a common result of this sort of scan. The scan merely
provides good information, not a perfect patch. There are two
possibilities:
1) The scan is right, and the dereference is dangerous. The
patch is correct.
2) The dereference is not dangerous ("can't happen"), and the
later check for NULL is spurious. A correct patch would
merely remove the check.
This is clearly a case of (2), but I bet that (1) is seen just
as often.
Joel
--
Life's Little Instruction Book #444
"Never underestimate the power of a kind word or deed."
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker@oracle.com
Phone: (650) 506-8127
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ocfs2: dereference before NULL check in ocfs2_direct_IO_get_blocks()
2006-06-03 19:15 ` Alexey Dobriyan
2006-06-03 21:16 ` Joel Becker
@ 2006-06-03 23:30 ` Florin Malita
2006-06-05 16:55 ` Mark Fasheh
1 sibling, 1 reply; 6+ messages in thread
From: Florin Malita @ 2006-06-03 23:30 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: mark.fasheh, kurt.hackel, linux-kernel, akpm
Alexey Dobriyan wrote:
> AFAICS, the patch is BS, as usual with this type of patches.
>
You missed the full purpose: the patch makes a function consistent about
its own assumptions (but leaves them in place since they're on the
better-safe-than-sorry side). It addresses assumptions inconsistency
(confusing for both human readers and static analysis tools) just as
much as it addresses a possible bug. Regardless of whether "inode" &
"bh_result" can be NULL, I don't think the following is OK (coding-wise):
unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
if (!inode || !bh_result) {
mlog(ML_ERROR, "inode or bh_result is null\n");
return -EIO;
}
> Can "inode" and "bh_result" be NULL here? I bet they can't
Great, then the NULL branch is dead code and we can fix consistency
differently:
Signed-off-by: Florin Malita <fmalita@gmail.com>
---
fs/ocfs2/aops.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 47152bf..370c241 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -558,16 +558,9 @@ static int ocfs2_direct_IO_get_blocks(st
u64 vbo_max; /* file offset, max_blocks from iblock */
u64 p_blkno;
int contig_blocks;
- unsigned char blocksize_bits;
+ unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
- if (!inode || !bh_result) {
- mlog(ML_ERROR, "inode or bh_result is null\n");
- return -EIO;
- }
-
- blocksize_bits = inode->i_sb->s_blocksize_bits;
-
/* This function won't even be called if the request isn't all
* nicely aligned and of the right size, so there's no need
* for us to check any of that. */
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] ocfs2: dereference before NULL check in ocfs2_direct_IO_get_blocks()
2006-06-03 21:16 ` Joel Becker
@ 2006-06-04 9:15 ` Arjan van de Ven
0 siblings, 0 replies; 6+ messages in thread
From: Arjan van de Ven @ 2006-06-04 9:15 UTC (permalink / raw)
To: Joel Becker
Cc: Alexey Dobriyan, Florin Malita, mark.fasheh, kurt.hackel,
linux-kernel, akpm
On Sat, 2006-06-03 at 14:16 -0700, Joel Becker wrote:
> On Sat, Jun 03, 2006 at 11:15:58PM +0400, Alexey Dobriyan wrote:
> > On Sat, Jun 03, 2006 at 11:34:39AM -0400, Florin Malita wrote:
> > > 'bh_result' & 'inode' are explicitly checked against NULL so they
> > > shouldn't be dereferenced prior to that.
> > >
> > > Coverity ID: 1273, 1274.
> >
> > AFAICS, the patch is BS, as usual with this type of patches.
> >
> > Can "inode" and "bh_result" be NULL here? I bet they can't.
>
> This is a common result of this sort of scan. The scan merely
> provides good information, not a perfect patch. There are two
> possibilities:
>
> 1) The scan is right, and the dereference is dangerous. The
> patch is correct.
> 2) The dereference is not dangerous ("can't happen"), and the
> later check for NULL is spurious. A correct patch would
> merely remove the check.
>
> This is clearly a case of (2), but I bet that (1) is seen just
> as often.
and in case of (2); newer gcc is often smart enough to do that
automatically :)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ocfs2: dereference before NULL check in ocfs2_direct_IO_get_blocks()
2006-06-03 23:30 ` Florin Malita
@ 2006-06-05 16:55 ` Mark Fasheh
0 siblings, 0 replies; 6+ messages in thread
From: Mark Fasheh @ 2006-06-05 16:55 UTC (permalink / raw)
To: Florin Malita; +Cc: Alexey Dobriyan, kurt.hackel, linux-kernel, akpm
On Sat, Jun 03, 2006 at 07:30:10PM -0400, Florin Malita wrote:
> Great, then the NULL branch is dead code and we can fix consistency
> differently:
Ok, this one seems much more reasonable. Thanks for the patch Florin.
--Mark
--
Mark Fasheh
Senior Software Developer, Oracle
mark.fasheh@oracle.com
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-06-05 16:55 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-03 15:34 [PATCH] ocfs2: dereference before NULL check in ocfs2_direct_IO_get_blocks() Florin Malita
2006-06-03 19:15 ` Alexey Dobriyan
2006-06-03 21:16 ` Joel Becker
2006-06-04 9:15 ` Arjan van de Ven
2006-06-03 23:30 ` Florin Malita
2006-06-05 16:55 ` Mark Fasheh
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).