Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

jbd2: don't leak memory if setting up journal fails

In journal_init_common(), if we failed to allocate the j_wbuf array, or
if we failed to create the buffer_head for the journal superblock, we
leaked the memory allocated for the revocation tables. Fix this.

Cc: stable@vger.kernel.org # 4.9
Fixes: f0c9fd5458bacf7b12a9a579a727dc740cbe047e
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>

authored by

Eric Biggers and committed by
Theodore Ts'o
cd9cb405 b9cf625d

+12 -11
+11 -11
fs/jbd2/journal.c
··· 1125 1125 1126 1126 /* Set up a default-sized revoke table for the new mount. */ 1127 1127 err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH); 1128 - if (err) { 1129 - kfree(journal); 1130 - return NULL; 1131 - } 1128 + if (err) 1129 + goto err_cleanup; 1132 1130 1133 1131 spin_lock_init(&journal->j_history_lock); 1134 1132 ··· 1143 1145 journal->j_wbufsize = n; 1144 1146 journal->j_wbuf = kmalloc_array(n, sizeof(struct buffer_head *), 1145 1147 GFP_KERNEL); 1146 - if (!journal->j_wbuf) { 1147 - kfree(journal); 1148 - return NULL; 1149 - } 1148 + if (!journal->j_wbuf) 1149 + goto err_cleanup; 1150 1150 1151 1151 bh = getblk_unmovable(journal->j_dev, start, journal->j_blocksize); 1152 1152 if (!bh) { 1153 1153 pr_err("%s: Cannot get buffer for journal superblock\n", 1154 1154 __func__); 1155 - kfree(journal->j_wbuf); 1156 - kfree(journal); 1157 - return NULL; 1155 + goto err_cleanup; 1158 1156 } 1159 1157 journal->j_sb_buffer = bh; 1160 1158 journal->j_superblock = (journal_superblock_t *)bh->b_data; 1161 1159 1162 1160 return journal; 1161 + 1162 + err_cleanup: 1163 + kfree(journal->j_wbuf); 1164 + jbd2_journal_destroy_revoke(journal); 1165 + kfree(journal); 1166 + return NULL; 1163 1167 } 1164 1168 1165 1169 /* jbd2_journal_init_dev and jbd2_journal_init_inode:
+1
fs/jbd2/revoke.c
··· 280 280 281 281 fail1: 282 282 jbd2_journal_destroy_revoke_table(journal->j_revoke_table[0]); 283 + journal->j_revoke_table[0] = NULL; 283 284 fail0: 284 285 return -ENOMEM; 285 286 }