[PATCH] use-before-uninitialized value in ext3(2)_find_ goal

From: Mingming Cao
Date: Wed May 19 2004 - 13:53:53 EST


I am looking at the how the goal for block allocation is determined in
in ext3_find_goal(), so I wrote a very simple test to do random write by
one process on one file (write() ,then lseek then write then lseek).
The test shows a bug there.

There is a uninitialized goal value being referenced in both ext3 and
ext2 find goal block functions (ext3_find_goal() and ext2_find_goal()).
In the non-sequential write case, these functions check the goal
value(non zero) before calling ext3(2)_find_near() to find the goal
block to allocate. Since the goal value is uninitialized(non zero), the
ext3(2)_find_near() is never being called in the non-sequential write,
thus ext3(2)_find_goal() failed to guide a goal block in the random
write case.

ext3(2)_new_block() takes the junk goal value and will turn it to goal 0
since it's normally beyond the filesystem block number limit.

The fix is trivial.

There is a uninitialized goal value being referenced in both ext3 and ext2 find goal block functions (ext3_find_goal() and ext2_find_goal()). In the non-sequential write case, these functions check the goal value(non zero) before calling ext3(2)_find_near() to find the goal block to allocate. Since the goal value is uninitialized(non zero), the ext3(2)_find_near() is never being called in the non-sequential write, thus ext3(2)_find_goal() failed to guide a goal block in the random write case. ext3(2)_new_block() takes the junk goal value and will turn it to goal 0 since it's normally beyond the filesystem block number limit. The fix is trivial.


---

src-ming/fs/ext2/inode.c | 1 +
src-ming/fs/ext3/inode.c | 1 +
2 files changed, 2 insertions(+)

diff -puN fs/ext3/inode.c~ext3_find_goal_uninitialization_fix fs/ext3/inode.c
--- src/fs/ext3/inode.c~ext3_find_goal_uninitialization_fix 2004-05-19 18:30:13.857197080 -0700
+++ src-ming/fs/ext3/inode.c 2004-05-19 18:45:31.689665336 -0700
@@ -748,6 +748,7 @@ out:
if (err == -EAGAIN)
goto changed;

+ goal = 0;
down(&ei->truncate_sem);
if (ext3_find_goal(inode, iblock, chain, partial, &goal) < 0) {
up(&ei->truncate_sem);
diff -puN fs/ext2/inode.c~ext3_find_goal_uninitialization_fix fs/ext2/inode.c
--- src/fs/ext2/inode.c~ext3_find_goal_uninitialization_fix 2004-05-19 18:30:13.861196472 -0700
+++ src-ming/fs/ext2/inode.c 2004-05-19 18:45:40.586312840 -0700
@@ -584,6 +584,7 @@ out:
if (err == -EAGAIN)
goto changed;

+ goal = 0;
if (ext2_find_goal(inode, iblock, chain, partial, &goal) < 0)
goto changed;


_

There is a uninitialized goal value being referenced in both ext3 and ext2 find goal block functions (ext3_find_goal() and ext2_find_goal()). In the non-sequential write case, these functions check the goal value(non zero) before calling ext3(2)_find_near() to find the goal block to allocate. Since the goal value is uninitialized(non zero), the ext3(2)_find_near() is never being called in the non-sequential write, thus ext3(2)_find_goal() failed to guide a goal block in the random write case. ext3(2)_new_block() takes the junk goal value and will turn it to goal 0 since it's normally beyond the filesystem block number limit. The fix is trivial.


---

src-ming/fs/ext2/inode.c | 1 +
src-ming/fs/ext3/inode.c | 1 +
2 files changed, 2 insertions(+)

diff -puN fs/ext3/inode.c~ext3_find_goal_unintialization_fix fs/ext3/inode.c
--- src/fs/ext3/inode.c~ext3_find_goal_unintialization_fix 2004-05-19 18:30:13.857197080 -0700
+++ src-ming/fs/ext3/inode.c 2004-05-19 18:45:31.689665336 -0700
@@ -748,6 +748,7 @@ out:
if (err == -EAGAIN)
goto changed;

+ goal = 0;
down(&ei->truncate_sem);
if (ext3_find_goal(inode, iblock, chain, partial, &goal) < 0) {
up(&ei->truncate_sem);
diff -puN fs/ext2/inode.c~ext3_find_goal_unintialization_fix fs/ext2/inode.c
--- src/fs/ext2/inode.c~ext3_find_goal_unintialization_fix 2004-05-19 18:30:13.861196472 -0700
+++ src-ming/fs/ext2/inode.c 2004-05-19 18:45:40.586312840 -0700
@@ -584,6 +584,7 @@ out:
if (err == -EAGAIN)
goto changed;

+ goal = 0;
if (ext2_find_goal(inode, iblock, chain, partial, &goal) < 0)
goto changed;


_