Details
-
Bug
-
Resolution: Fixed
-
Critical
-
None
-
3
-
9223372036854775807
Description
The failure happened at
[27870519.051376] BUG: unable to handle kernel NULL pointer dereference at (null) [27870519.058800] IP: [<ffffffffa067cac9>] lu_device_put+0x9/0x50 [obdclass] [27870519.065736] PGD 59d964067 PUD e912b8067 PMD 0 [27870519.070586] Oops: 0000 [#1] SMP [27870519.074201] last sysfs file: /sys/module/ipv6/initstate [27870519.079770] CPU 7 … [27870519.176276] Pid: 92764, comm: jbd2/md141 Tainted: P --------------- 2.6.32-431.17.1.x2.0.87.x86_64 #1 Seagate SATI-TL/Type2 - Board Product Sati2 [27870519.190999] RIP: 0010:[<ffffffffa067cac9>] [<ffffffffa067cac9>] lu_device_put+0x9/0x50 [obdclass] [.... [27870519.282591] Process jbd2/md141 (pid: 92764, threadinfo ffff8805c6f3e000, task ffff880e833a8ae0) [27870519.291704] Stack: [27870519.294056] ffff8805c6f3fcf0 ffffffffa0f25acb ffff8805c6f3fcd0 ffff880592d0d4e8 [27870519.301689] <d> ffff880f43897a98 0000000000000000 ffff880c18808800 0000000000f36fcb [27870519.309871] <d> ffff8805c6f3fd20 ffffffffa0ecc8e1 ffff8809650ddb9c ffff880f438979c0 [27870519.318320] Call Trace: [27870519.321125] [<ffffffffa0f25acb>] osd_trans_commit_cb+0xcb/0x2b0 [osd_ldiskfs] [27870519.328780] [<ffffffffa0ecc8e1>] ldiskfs_journal_commit_callback+0x61/0x80 [ldiskfs] [27870519.337036] [<ffffffffa03eb8ef>] jbd2_journal_commit_transaction+0x116f/0x15a0 [jbd2]
The transaction was allocated at slab-256. The slab element before transaction belongs to ldiskfs ext path, executed function is ldiskfs_ext_remove_space().
There is a bug in a while loop where bread is called.
depth = ext_depth(inode);
if (path) {
int k = i = depth;
while (--k > 0)
path[k].p_block =
le16_to_cpu(path[k].p_hdr->eh_entries)+1;
} else {
path = kzalloc(sizeof(struct ldiskfs_ext_path) *
LDISKFS_SB(inode->i_sb)->s_max_ext_tree_depth,
GFP_NOFS);
if (path == NULL) {
ldiskfs_journal_stop(handle);
return -ENOMEM;
}
path[0].p_depth = depth;
path[0].p_hdr = ext_inode_hdr(inode);
i = 0;
if (ldiskfs_ext_check(inode, path[0].p_hdr, depth, 0)) {
err = -EIO;
goto out;
}
}
err = 0;
while (i >= 0 && err == 0) {
if (i == depth) {
/* this is leaf block */
err = ldiskfs_ext_rm_leaf(handle, inode, path,
&partial_cluster, start,
end);
/* root level has p_bh == NULL, brelse() eats this */
brelse(path[i].p_bh);
path[i].p_bh = NULL;
i--;
continue;
}
...
memset(path + i + 1, 0, sizeof(*path));
bh = read_extent_tree_block(inode,
ldiskfs_idx_pblock(path[i].p_idx), depth - i - 1,
LDISKFS_EX_NOCACHE);
if (IS_ERR(bh)) {
/* should we reset i_size? */
err = PTR_ERR(bh);
break;
}
The allocation was done for s_max_ext_tree_depth elements. Iteration index start with 0. And compared with depth(number of elements). So
memset(path + i + 1, 0, sizeof(*path));
could zero memory outside the allocation. The depth is 5 at vmcore.