Skip to content

Commit afc1e64

Browse files
committed
Merge: Ext4: Update for rhel9.5
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/4410 JIRA: https://issues.redhat.com/browse/RHEL-36282 JIRA: https://issues.redhat.com/browse/RHEL-36976 JIRA: https://issues.redhat.com/browse/RHEL-31702 CVE: CVE-2024-26772 CVE: CVE-2024-35807 Tested: with xfstests Update jbd2 and ext4 for RHEL9.5 Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Approved-by: Eric Sandeen <esandeen@redhat.com> Approved-by: Pavel Reichl <preichl@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Lucas Zampieri <lzampier@redhat.com>
2 parents 3c0c8e0 + 71458e9 commit afc1e64

File tree

20 files changed

+743
-776
lines changed

20 files changed

+743
-776
lines changed

fs/ext4/balloc.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,8 @@ static unsigned ext4_num_overhead_clusters(struct super_block *sb,
111111
itbl_blk_start = ext4_inode_table(sb, gdp);
112112
itbl_blk_end = itbl_blk_start + sbi->s_itb_per_group - 1;
113113
if (itbl_blk_start <= end && itbl_blk_end >= start) {
114-
itbl_blk_start = itbl_blk_start >= start ?
115-
itbl_blk_start : start;
116-
itbl_blk_end = itbl_blk_end <= end ?
117-
itbl_blk_end : end;
114+
itbl_blk_start = max(itbl_blk_start, start);
115+
itbl_blk_end = min(itbl_blk_end, end);
118116

119117
itbl_cluster_start = EXT4_B2C(sbi, itbl_blk_start - start);
120118
itbl_cluster_end = EXT4_B2C(sbi, itbl_blk_end - start);

fs/ext4/crypto.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
3333

3434
#if IS_ENABLED(CONFIG_UNICODE)
3535
err = ext4_fname_setup_ci_filename(dir, iname, fname);
36+
if (err)
37+
ext4_fname_free_filename(fname);
3638
#endif
3739
return err;
3840
}
@@ -51,6 +53,8 @@ int ext4_fname_prepare_lookup(struct inode *dir, struct dentry *dentry,
5153

5254
#if IS_ENABLED(CONFIG_UNICODE)
5355
err = ext4_fname_setup_ci_filename(dir, &dentry->d_name, fname);
56+
if (err)
57+
ext4_fname_free_filename(fname);
5458
#endif
5559
return err;
5660
}

fs/ext4/ext4.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,6 +1526,7 @@ struct ext4_sb_info {
15261526
loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */
15271527
struct buffer_head * s_sbh; /* Buffer containing the super block */
15281528
struct ext4_super_block *s_es; /* Pointer to the super block in the buffer */
1529+
/* Array of bh's for the block group descriptors */
15291530
struct buffer_head * __rcu *s_group_desc;
15301531
unsigned int s_mount_opt;
15311532
unsigned int s_mount_opt2;
@@ -1596,7 +1597,7 @@ struct ext4_sb_info {
15961597
unsigned int *s_mb_maxs;
15971598
unsigned int s_group_info_size;
15981599
unsigned int s_mb_free_pending;
1599-
struct list_head s_freed_data_list; /* List of blocks to be freed
1600+
struct list_head s_freed_data_list[2]; /* List of blocks to be freed
16001601
after commit completed */
16011602
struct list_head s_discard_list;
16021603
struct work_struct s_discard_work;
@@ -1704,7 +1705,8 @@ struct ext4_sb_info {
17041705

17051706
/*
17061707
* Barrier between writepages ops and changing any inode's JOURNAL_DATA
1707-
* or EXTENTS flag.
1708+
* or EXTENTS flag or between writepages ops and changing DELALLOC or
1709+
* DIOREAD_NOLOCK mount options on remount.
17081710
*/
17091711
struct percpu_rw_semaphore s_writepages_rwsem;
17101712
struct dax_device *s_daxdev;
@@ -1732,10 +1734,13 @@ struct ext4_sb_info {
17321734
const char *s_last_error_func;
17331735
time64_t s_last_error_time;
17341736
/*
1735-
* If we are in a context where we cannot update error information in
1736-
* the on-disk superblock, we queue this work to do it.
1737+
* If we are in a context where we cannot update the on-disk
1738+
* superblock, we queue the work here. This is used to update
1739+
* the error information in the superblock, and for periodic
1740+
* updates of the superblock called from the commit callback
1741+
* function.
17371742
*/
1738-
struct work_struct s_error_work;
1743+
struct work_struct s_sb_upd_work;
17391744

17401745
/* Ext4 fast commit sub transaction ID */
17411746
atomic_t s_fc_subtid;

fs/ext4/extents.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,11 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
10101010
ix = curp->p_idx;
10111011
}
10121012

1013+
if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) {
1014+
EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!");
1015+
return -EFSCORRUPTED;
1016+
}
1017+
10131018
len = EXT_LAST_INDEX(curp->p_hdr) - ix + 1;
10141019
BUG_ON(len < 0);
10151020
if (len > 0) {
@@ -1019,11 +1024,6 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
10191024
memmove(ix + 1, ix, len * sizeof(struct ext4_extent_idx));
10201025
}
10211026

1022-
if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) {
1023-
EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!");
1024-
return -EFSCORRUPTED;
1025-
}
1026-
10271027
ix->ei_block = cpu_to_le32(logical);
10281028
ext4_idx_store_pblock(ix, ptr);
10291029
le16_add_cpu(&curp->p_hdr->eh_entries, 1);
@@ -4070,10 +4070,10 @@ static int get_implied_cluster_alloc(struct super_block *sb,
40704070
*
40714071
* Need to be called with
40724072
* down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
4073-
* (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
4073+
* (ie, flags is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
40744074
*
40754075
* return > 0, number of blocks already mapped/allocated
4076-
* if create == 0 and these are pre-allocated blocks
4076+
* if flags doesn't contain EXT4_GET_BLOCKS_CREATE and these are pre-allocated blocks
40774077
* buffer head is unmapped
40784078
* otherwise blocks are mapped
40794079
*
@@ -4177,7 +4177,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
41774177

41784178
/*
41794179
* requested block isn't allocated yet;
4180-
* we couldn't try to create block if create flag is zero
4180+
* we couldn't try to create block if flags doesn't contain EXT4_GET_BLOCKS_CREATE
41814181
*/
41824182
if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
41834183
ext4_lblk_t hole_start, hole_len;

fs/ext4/extents_status.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,8 +1363,8 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
13631363
}
13641364
}
13651365
if (count_reserved)
1366-
count_rsvd(inode, lblk, orig_es.es_len - len1 - len2,
1367-
&orig_es, &rc);
1366+
count_rsvd(inode, orig_es.es_lblk + len1,
1367+
orig_es.es_len - len1 - len2, &orig_es, &rc);
13681368
goto out_get_reserved;
13691369
}
13701370

fs/ext4/hash.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ int ext4fs_dirhash(const struct inode *dir, const char *name, int len,
300300
unsigned char *buff;
301301
struct qstr qstr = {.name = name, .len = len };
302302

303-
if (len && IS_CASEFOLDED(dir) && um &&
303+
if (len && IS_CASEFOLDED(dir) &&
304304
(!IS_ENCRYPTED(dir) || fscrypt_has_encryption_key(dir))) {
305305
buff = kzalloc(sizeof(char) * PATH_MAX, GFP_KERNEL);
306306
if (!buff)

fs/ext4/inode.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,10 @@ static void ext4_map_blocks_es_recheck(handle_t *handle,
494494
* Otherwise, call with ext4_ind_map_blocks() to handle indirect mapping
495495
* based files
496496
*
497-
* On success, it returns the number of blocks being mapped or allocated. if
498-
* create==0 and the blocks are pre-allocated and unwritten, the resulting @map
499-
* is marked as unwritten. If the create == 1, it will mark @map as mapped.
497+
* On success, it returns the number of blocks being mapped or allocated.
498+
* If flags doesn't contain EXT4_GET_BLOCKS_CREATE the blocks are
499+
* pre-allocated and unwritten, the resulting @map is marked as unwritten.
500+
* If the flags contain EXT4_GET_BLOCKS_CREATE, it will mark @map as mapped.
500501
*
501502
* It returns 0 if plain look up failed (blocks have not been allocated), in
502503
* that case, @map is returned as unmapped but we still do fill map->m_len to
@@ -618,8 +619,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
618619
* Returns if the blocks have already allocated
619620
*
620621
* Note that if blocks have been preallocated
621-
* ext4_ext_get_block() returns the create = 0
622-
* with buffer head unmapped.
622+
* ext4_ext_map_blocks() returns with buffer head unmapped
623623
*/
624624
if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED)
625625
/*
@@ -834,10 +834,22 @@ int ext4_get_block(struct inode *inode, sector_t iblock,
834834
int ext4_get_block_unwritten(struct inode *inode, sector_t iblock,
835835
struct buffer_head *bh_result, int create)
836836
{
837+
int ret = 0;
838+
837839
ext4_debug("ext4_get_block_unwritten: inode %lu, create flag %d\n",
838840
inode->i_ino, create);
839-
return _ext4_get_block(inode, iblock, bh_result,
841+
ret = _ext4_get_block(inode, iblock, bh_result,
840842
EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT);
843+
844+
/*
845+
* If the buffer is marked unwritten, mark it as new to make sure it is
846+
* zeroed out correctly in case of partial writes. Otherwise, there is
847+
* a chance of stale data getting exposed.
848+
*/
849+
if (ret == 0 && buffer_unwritten(bh_result))
850+
set_buffer_new(bh_result);
851+
852+
return ret;
841853
}
842854

843855
/* Maximum number of blocks we map for direct IO at once. */
@@ -5146,9 +5158,12 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
51465158
"iget: bogus i_mode (%o)", inode->i_mode);
51475159
goto bad_inode;
51485160
}
5149-
if (IS_CASEFOLDED(inode) && !ext4_has_feature_casefold(inode->i_sb))
5161+
if (IS_CASEFOLDED(inode) && !ext4_has_feature_casefold(inode->i_sb)) {
51505162
ext4_error_inode(inode, function, line, 0,
51515163
"casefold flag without casefold feature");
5164+
ret = -EFSCORRUPTED;
5165+
goto bad_inode;
5166+
}
51525167
if ((err_str = check_igot_inode(inode, flags)) != NULL) {
51535168
ext4_error_inode(inode, function, line, 0, err_str);
51545169
ret = -EFSCORRUPTED;

0 commit comments

Comments
 (0)