Unverified Commit 02b054ea authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!6030 Fix CVE-2024-26685

Merge Pull Request from: @ci-robot 
 
PR sync from: Zizhi Wo <wozizhi@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/RYT7PIQ2INUZLBEGXA7OGBH45SIKJ7SQ/ 
Fixup the CVE-2024-26685

Ryusuke Konishi (2):
  nilfs2: fix buffer corruption due to concurrent device reads
  nilfs2: fix potential bug in end_buffer_async_write


-- 
2.39.2
 
https://gitee.com/src-openeuler/kernel/issues/I9E2FP 
 
Link:https://gitee.com/openeuler/kernel/pulls/6030

 

Reviewed-by: default avatarLiu YongQiang <liuyongqiang13@huawei.com>
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
parents 73321102 ec3e7aad
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -101,6 +101,12 @@ int nilfs_segbuf_extend_segsum(struct nilfs_segment_buffer *segbuf)
	if (unlikely(!bh))
		return -ENOMEM;

	lock_buffer(bh);
	if (!buffer_uptodate(bh)) {
		memset(bh->b_data, 0, bh->b_size);
		set_buffer_uptodate(bh);
	}
	unlock_buffer(bh);
	nilfs_segbuf_add_segsum_buffer(segbuf, bh);
	return 0;
}
+12 −3
Original line number Diff line number Diff line
@@ -956,10 +956,13 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
	unsigned int isz, srsz;

	bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root;

	lock_buffer(bh_sr);
	raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
	isz = nilfs->ns_inode_size;
	srsz = NILFS_SR_BYTES(isz);

	raw_sr->sr_sum = 0;  /* Ensure initialization within this update */
	raw_sr->sr_bytes = cpu_to_le16(srsz);
	raw_sr->sr_nongc_ctime
		= cpu_to_le64(nilfs_doing_gc() ?
@@ -973,6 +976,8 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
	nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr +
				 NILFS_SR_SUFILE_OFFSET(isz), 1);
	memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz);
	set_buffer_uptodate(bh_sr);
	unlock_buffer(bh_sr);
}

static void nilfs_redirty_inodes(struct list_head *head)
@@ -1663,7 +1668,6 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)

		list_for_each_entry(bh, &segbuf->sb_payload_buffers,
				    b_assoc_buffers) {
			set_buffer_async_write(bh);
			if (bh == segbuf->sb_super_root) {
				if (bh->b_page != bd_page) {
					lock_page(bd_page);
@@ -1674,6 +1678,7 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
				}
				break;
			}
			set_buffer_async_write(bh);
			if (bh->b_page != fs_page) {
				nilfs_begin_page_io(fs_page);
				fs_page = bh->b_page;
@@ -1749,6 +1754,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err)
	list_for_each_entry(segbuf, logs, sb_list) {
		list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
				    b_assoc_buffers) {
			clear_buffer_uptodate(bh);
			if (bh->b_page != bd_page) {
				if (bd_page)
					end_page_writeback(bd_page);
@@ -1758,14 +1764,15 @@ static void nilfs_abort_logs(struct list_head *logs, int err)

		list_for_each_entry(bh, &segbuf->sb_payload_buffers,
				    b_assoc_buffers) {
			clear_buffer_async_write(bh);
			if (bh == segbuf->sb_super_root) {
				clear_buffer_uptodate(bh);
				if (bh->b_page != bd_page) {
					end_page_writeback(bd_page);
					bd_page = bh->b_page;
				}
				break;
			}
			clear_buffer_async_write(bh);
			if (bh->b_page != fs_page) {
				nilfs_end_page_io(fs_page, err);
				fs_page = bh->b_page;
@@ -1853,8 +1860,9 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
				 BIT(BH_Delay) | BIT(BH_NILFS_Volatile) |
				 BIT(BH_NILFS_Redirected));

			set_mask_bits(&bh->b_state, clear_bits, set_bits);
			if (bh == segbuf->sb_super_root) {
				set_buffer_uptodate(bh);
				clear_buffer_dirty(bh);
				if (bh->b_page != bd_page) {
					end_page_writeback(bd_page);
					bd_page = bh->b_page;
@@ -1862,6 +1870,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
				update_sr = true;
				break;
			}
			set_mask_bits(&bh->b_state, clear_bits, set_bits);
			if (bh->b_page != fs_page) {
				nilfs_end_page_io(fs_page, 0);
				fs_page = bh->b_page;
+22 −1
Original line number Diff line number Diff line
@@ -373,10 +373,31 @@ static int nilfs_move_2nd_super(struct super_block *sb, loff_t sb2off)
		goto out;
	}
	nsbp = (void *)nsbh->b_data + offset;
	memset(nsbp, 0, nilfs->ns_blocksize);

	lock_buffer(nsbh);
	if (sb2i >= 0) {
		/*
		 * The position of the second superblock only changes by 4KiB,
		 * which is larger than the maximum superblock data size
		 * (= 1KiB), so there is no need to use memmove() to allow
		 * overlap between source and destination.
		 */
		memcpy(nsbp, nilfs->ns_sbp[sb2i], nilfs->ns_sbsize);

		/*
		 * Zero fill after copy to avoid overwriting in case of move
		 * within the same block.
		 */
		memset(nsbh->b_data, 0, offset);
		memset((void *)nsbp + nilfs->ns_sbsize, 0,
		       nsbh->b_size - offset - nilfs->ns_sbsize);
	} else {
		memset(nsbh->b_data, 0, nsbh->b_size);
	}
	set_buffer_uptodate(nsbh);
	unlock_buffer(nsbh);

	if (sb2i >= 0) {
		brelse(nilfs->ns_sbh[sb2i]);
		nilfs->ns_sbh[sb2i] = nsbh;
		nilfs->ns_sbp[sb2i] = nsbp;