• Lukas Czerner's avatar
    ext4: fix NULL pointer dereference when journal restart fails · 9d506594
    Lukas Czerner authored
    Currently when journal restart fails, we'll have the h_transaction of
    the handle set to NULL to indicate that the handle has been effectively
    aborted. We handle this situation quietly in the jbd2_journal_stop() and just
    free the handle and exit because everything else has been done before we
    attempted (and failed) to restart the journal.
    
    Unfortunately there are a number of problems with that approach
    introduced with commit
    
    41a5b913 "jbd2: invalidate handle if jbd2_journal_restart()
    fails"
    
    First of all in ext4 jbd2_journal_stop() will be called through
    __ext4_journal_stop() where we would try to get a hold of the superblock
    by dereferencing h_transaction which in this case would lead to NULL
    pointer dereference and crash.
    
    In addition we're going to free the handle regardless of the refcount
    which is bad as well, because others up the call chain will still
    reference the handle so we might potentially reference already freed
    memory.
    
    Moreover it's expected that we'll get aborted handle as well as detached
    handle in some of the journalling function as the error propagates up
    the stack, so it's unnecessary to call WARN_ON every time we get
    detached handle.
    
    And finally we might leak some memory by forgetting to free reserved
    handle in jbd2_journal_stop() in the case where handle was detached from
    the transaction (h_transaction is NULL).
    
    Fix the NULL pointer dereference in __ext4_journal_stop() by just
    calling jbd2_journal_stop() quietly as suggested by Jan Kara. Also fix
    the potential memory leak in jbd2_journal_stop() and use proper
    handle refcounting before we attempt to free it to avoid use-after-free
    issues.
    
    And finally remove all WARN_ON(!transaction) from the code so that we do
    not get random traces when something goes wrong because when journal
    restart fails we will get to some of those functions.
    
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarLukas Czerner <lczerner@redhat.com>
    Signed-off-by: Theodore Ts'o's avatarTheodore Ts'o <tytso@mit.edu>
    Reviewed-by: default avatarJan Kara <jack@suse.cz>
    9d506594
Name
Last commit
Last update
..
9p Loading commit data...
adfs Loading commit data...
affs Loading commit data...
afs Loading commit data...
autofs4 Loading commit data...
befs Loading commit data...
bfs Loading commit data...
btrfs Loading commit data...
cachefiles Loading commit data...
ceph Loading commit data...
cifs Loading commit data...
coda Loading commit data...
configfs Loading commit data...
cramfs Loading commit data...
debugfs Loading commit data...
devpts Loading commit data...
dlm Loading commit data...
ecryptfs Loading commit data...
efivarfs Loading commit data...
efs Loading commit data...
exofs Loading commit data...
exportfs Loading commit data...
ext2 Loading commit data...
ext3 Loading commit data...
ext4 Loading commit data...
f2fs Loading commit data...
fat Loading commit data...
freevxfs Loading commit data...
fscache Loading commit data...
fuse Loading commit data...
gfs2 Loading commit data...
hfs Loading commit data...
hfsplus Loading commit data...
hostfs Loading commit data...
hpfs Loading commit data...
hppfs Loading commit data...
hugetlbfs Loading commit data...
isofs Loading commit data...
jbd Loading commit data...
jbd2 Loading commit data...
jffs2 Loading commit data...
jfs Loading commit data...
kernfs Loading commit data...
lockd Loading commit data...
logfs Loading commit data...
minix Loading commit data...
ncpfs Loading commit data...
nfs Loading commit data...
nfs_common Loading commit data...
nfsd Loading commit data...
nilfs2 Loading commit data...
nls Loading commit data...
notify Loading commit data...
ntfs Loading commit data...
ocfs2 Loading commit data...
omfs Loading commit data...
openpromfs Loading commit data...
overlayfs Loading commit data...
proc Loading commit data...
pstore Loading commit data...
qnx4 Loading commit data...
qnx6 Loading commit data...
quota Loading commit data...
ramfs Loading commit data...
reiserfs Loading commit data...
romfs Loading commit data...
squashfs Loading commit data...
sysfs Loading commit data...
sysv Loading commit data...
tracefs Loading commit data...
ubifs Loading commit data...
udf Loading commit data...
ufs Loading commit data...
xfs Loading commit data...
Kconfig Loading commit data...
Kconfig.binfmt Loading commit data...
Makefile Loading commit data...
aio.c Loading commit data...
anon_inodes.c Loading commit data...
attr.c Loading commit data...
bad_inode.c Loading commit data...
binfmt_aout.c Loading commit data...
binfmt_elf.c Loading commit data...
binfmt_elf_fdpic.c Loading commit data...
binfmt_em86.c Loading commit data...
binfmt_flat.c Loading commit data...
binfmt_misc.c Loading commit data...
binfmt_script.c Loading commit data...
block_dev.c Loading commit data...
buffer.c Loading commit data...
char_dev.c Loading commit data...
compat.c Loading commit data...
compat_binfmt_elf.c Loading commit data...
compat_ioctl.c Loading commit data...
coredump.c Loading commit data...
dax.c Loading commit data...
dcache.c Loading commit data...
dcookies.c Loading commit data...
direct-io.c Loading commit data...
drop_caches.c Loading commit data...
eventfd.c Loading commit data...
eventpoll.c Loading commit data...
exec.c Loading commit data...
fcntl.c Loading commit data...
fhandle.c Loading commit data...
file.c Loading commit data...
file_table.c Loading commit data...
filesystems.c Loading commit data...
fs-writeback.c Loading commit data...
fs_pin.c Loading commit data...
fs_struct.c Loading commit data...
inode.c Loading commit data...
internal.h Loading commit data...
ioctl.c Loading commit data...
libfs.c Loading commit data...
locks.c Loading commit data...
mbcache.c Loading commit data...
mount.h Loading commit data...
mpage.c Loading commit data...
namei.c Loading commit data...
namespace.c Loading commit data...
no-block.c Loading commit data...
nsfs.c Loading commit data...
open.c Loading commit data...
pipe.c Loading commit data...
pnode.c Loading commit data...
pnode.h Loading commit data...
posix_acl.c Loading commit data...
proc_namespace.c Loading commit data...
read_write.c Loading commit data...
readdir.c Loading commit data...
select.c Loading commit data...
seq_file.c Loading commit data...
signalfd.c Loading commit data...
splice.c Loading commit data...
stack.c Loading commit data...
stat.c Loading commit data...
statfs.c Loading commit data...
super.c Loading commit data...
sync.c Loading commit data...
timerfd.c Loading commit data...
utimes.c Loading commit data...
xattr.c Loading commit data...