From d9fd79f81ca10a656023596340284fb1c3b1b9ed Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 12 Mar 2016 21:56:08 -0500 Subject: [PATCH] add patch fix-NULL-pointer-dereference-in-ext4_mark_inode_dirty --- ...LL-pointer-dereference-in-ext4_mark_inode_dirty | 81 ++++++++++++++++++++++ series | 1 + timestamps | 5 +- 3 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 fix-NULL-pointer-dereference-in-ext4_mark_inode_dirty diff --git a/fix-NULL-pointer-dereference-in-ext4_mark_inode_dirty b/fix-NULL-pointer-dereference-in-ext4_mark_inode_dirty new file mode 100644 index 00000000..dc9ef668 --- /dev/null +++ b/fix-NULL-pointer-dereference-in-ext4_mark_inode_dirty @@ -0,0 +1,81 @@ +ext4: fix NULL pointer dereference in ext4_mark_inode_dirty() + +From: Eryu Guan + +ext4_reserve_inode_write() in ext4_mark_inode_dirty() could fail on +error (e.g. EIO) and iloc.bh can be NULL in this case. But the error is +ignored in the following "if" condition and ext4_expand_extra_isize() +might be called with NULL iloc.bh set, which triggers NULL pointer +dereference. + +This is uncovered by commit 8b4953e13f4c ("ext4: reserve code points for +the project quota feature"), which enlarges the ext4_inode size, and +run the following script on new kernel but with old mke2fs: + + #/bin/bash + mnt=/mnt/ext4 + devname=ext4-error + dev=/dev/mapper/$devname + fsimg=/home/fs.img + + trap cleanup 0 1 2 3 9 15 + + cleanup() + { + umount $mnt >/dev/null 2>&1 + dmsetup remove $devname + losetup -d $backend_dev + rm -f $fsimg + exit 0 + } + + rm -f $fsimg + fallocate -l 1g $fsimg + backend_dev=`losetup -f --show $fsimg` + devsize=`blockdev --getsz $backend_dev` + + good_tab="0 $devsize linear $backend_dev 0" + error_tab="0 $devsize error $backend_dev 0" + + dmsetup create $devname --table "$good_tab" + + mkfs -t ext4 $dev + mount -t ext4 -o errors=continue,strictatime $dev $mnt + + dmsetup load $devname --table "$error_tab" && dmsetup resume $devname + echo 3 > /proc/sys/vm/drop_caches + ls -l $mnt + exit 0 + +[ Patch changed to simplify the function a tiny bit. -- Ted ] + +Signed-off-by: Eryu Guan +Signed-off-by: Theodore Ts'o +--- + fs/ext4/inode.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index ce2c4c6..b41432e 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -5312,6 +5312,8 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) + might_sleep(); + trace_ext4_mark_inode_dirty(inode, _RET_IP_); + err = ext4_reserve_inode_write(handle, inode, &iloc); ++ if (err) ++ return err; + if (ext4_handle_valid(handle) && + EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && + !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) { +@@ -5342,9 +5344,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) + } + } + } +- if (!err) +- err = ext4_mark_iloc_dirty(handle, inode, &iloc); +- return err; ++ return ext4_mark_iloc_dirty(handle, inode, &iloc); + } + + /* diff --git a/series b/series index 69c22b0a..4719a265 100644 --- a/series +++ b/series @@ -39,6 +39,7 @@ more-efficient-SEEK_DATA-implementation fix-jbd2_journal_destroy-for-umount-path fix-misspellings-in-comments drop-unneeded-BUFFER_TRACE-in-ext4_delete_inline_entry +fix-NULL-pointer-dereference-in-ext4_mark_inode_dirty ########################################## # unstable patches diff --git a/timestamps b/timestamps index b41bdfa9..fac5ece6 100755 --- a/timestamps +++ b/timestamps @@ -60,7 +60,8 @@ touch -d @1457583073 more-efficient-SEEK_DATA-implementation touch -d @1457585245 fix-jbd2_journal_destroy-for-umount-path touch -d @1457585345 fix-misspellings-in-comments touch -d @1457587137 drop-unneeded-BUFFER_TRACE-in-ext4_delete_inline_entry -touch -d @1457587153 series touch -d @1457587197 stable-boundary -touch -d @1457834565 status touch -d @1457835388 timestamps +touch -d @1457836365 series +touch -d @1457836832 fix-NULL-pointer-dereference-in-ext4_mark_inode_dirty +touch -d @1457836832 status -- 2.11.4.GIT