2004-04-27 06:56:57

by Junfeng Yang

[permalink] [raw]
Subject: [CHECKER] A derefence of null pointer errorin JFS (jfs2.4, kernel 2.4.19)


file fs/jfs/jfs_tree.c
-----------------------------------------------------------
[BUG] get_metapage can return null when grab_cache_page or read_cache_page
fails in function __get_metapage. In that case, mp

jfs_tree.c
static int dtSplitRoot(tid_t tid,
struct inode *ip, struct dtsplit * split, struct metapage ** rmpp)
{
....
pxdlist = split->pxdlist;
pxd = &pxdlist->pxd[pxdlist->npxd];
pxdlist->npxd++;
rbn = addressPXD(pxd);
xlen = lengthPXD(pxd);
xsize = xlen << JFS_SBI(sb)->l2bsize;
rmp = get_metapage(ip, rbn, xsize, 1);
ERROR-->rp = rmp->data;
...
}


jfs_metapage.c
struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
unsigned int size, int absolute,
unsigned long new)
{
......
if (new) {
jfs_info("__get_metapage: Calling grab_cache_page");
FAIL---> mp->page = grab_cache_page(mapping, page_index);
if (!mp->page) {
jfs_err("grab_cache_page failed!");
goto freeit;
} else {
INCREMENT(mpStat.pagealloc);
UnlockPage(mp->page);
}
} else {
jfs_info("__get_metapage: Calling read_cache_page");
FAIL---> mp->page = read_cache_page(mapping, lblock,
(filler_t *)mapping->a_ops->readpage, NULL);
if (IS_ERR(mp->page)) {
jfs_err("read_cache_page failed!");
goto freeit;
} else
INCREMENT(mpStat.pagealloc);
}
mp->data = kmap(mp->page) + page_offset;
}
jfs_info("__get_metapage: returning = 0x%p", mp);
return mp;

freeit:
spin_lock(&meta_lock);
remove_from_hash(mp, hash_ptr);
__free_metapage(mp);
spin_unlock(&meta_lock);
return NULL;
}


2004-04-30 19:05:34

by Dave Kleikamp

[permalink] [raw]
Subject: Re: [CHECKER] A derefence of null pointer errorin JFS (jfs2.4, kernel 2.4.19)

On Tue, 2004-04-27 at 01:56, Junfeng Yang wrote:
> file fs/jfs/jfs_dtree.c
> -----------------------------------------------------------
> [BUG] get_metapage can return null when grab_cache_page or read_cache_page
> fails in function __get_metapage.

Thanks. This patch should fix it. I'll submit the fix to Linus &
Marcelo.

Shaggy

===== fs/jfs/jfs_dtree.c 1.27 vs edited =====
--- 1.27/fs/jfs/jfs_dtree.c Wed Mar 24 14:11:46 2004
+++ edited/fs/jfs/jfs_dtree.c Fri Apr 30 13:47:31 2004
@@ -982,7 +982,9 @@
split->pxdlist = &pxdlist;
rc = dtSplitRoot(tid, ip, split, &rmp);

- DT_PUTPAGE(rmp);
+ if (!rc)
+ DT_PUTPAGE(rmp);
+
DT_PUTPAGE(smp);

goto freeKeyName;
@@ -1876,6 +1878,9 @@
xlen = lengthPXD(pxd);
xsize = xlen << JFS_SBI(sb)->l2bsize;
rmp = get_metapage(ip, rbn, xsize, 1);
+ if (!rmp)
+ return -EIO;
+
rp = rmp->data;

BT_MARK_DIRTY(rmp, ip);

--
David Kleikamp
IBM Linux Technology Center