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

Configure Feed

Select the types of activity you want to include in your feed.

ext4: fix unaligned memory access in ext4_fc_reserve_space()

As is done elsewhere in the file, build the struct ext4_fc_tl on the
stack and memcpy() it into the buffer, rather than directly writing it
to a potentially-unaligned location in the buffer.

Fixes: aa75f4d3daae ("ext4: main fast-commit commit path")
Cc: <stable@vger.kernel.org> # v5.10+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Link: https://lore.kernel.org/r/20221106224841.279231-6-ebiggers@kernel.org
Signed-off-by: Theodore Ts'o <tytso@mit.edu>

authored by

Eric Biggers and committed by
Theodore Ts'o
8415ce07 64b4a25c

+21 -18
+21 -18
fs/ext4/fast_commit.c
··· 675 675 676 676 /* Ext4 commit path routines */ 677 677 678 + /* memcpy to fc reserved space and update CRC */ 679 + static void *ext4_fc_memcpy(struct super_block *sb, void *dst, const void *src, 680 + int len, u32 *crc) 681 + { 682 + if (crc) 683 + *crc = ext4_chksum(EXT4_SB(sb), *crc, src, len); 684 + return memcpy(dst, src, len); 685 + } 686 + 678 687 /* memzero and update CRC */ 679 688 static void *ext4_fc_memzero(struct super_block *sb, void *dst, int len, 680 689 u32 *crc) ··· 709 700 */ 710 701 static u8 *ext4_fc_reserve_space(struct super_block *sb, int len, u32 *crc) 711 702 { 712 - struct ext4_fc_tl *tl; 703 + struct ext4_fc_tl tl; 713 704 struct ext4_sb_info *sbi = EXT4_SB(sb); 714 705 struct buffer_head *bh; 715 706 int bsize = sbi->s_journal->j_blocksize; 716 707 int ret, off = sbi->s_fc_bytes % bsize; 717 708 int pad_len; 709 + u8 *dst; 718 710 719 711 /* 720 712 * After allocating len, we should have space at least for a 0 byte ··· 739 729 return sbi->s_fc_bh->b_data + off; 740 730 } 741 731 /* Need to add PAD tag */ 742 - tl = (struct ext4_fc_tl *)(sbi->s_fc_bh->b_data + off); 743 - tl->fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD); 732 + dst = sbi->s_fc_bh->b_data + off; 733 + tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD); 744 734 pad_len = bsize - off - 1 - EXT4_FC_TAG_BASE_LEN; 745 - tl->fc_len = cpu_to_le16(pad_len); 746 - if (crc) 747 - *crc = ext4_chksum(sbi, *crc, tl, EXT4_FC_TAG_BASE_LEN); 748 - if (pad_len > 0) 749 - ext4_fc_memzero(sb, tl + 1, pad_len, crc); 735 + tl.fc_len = cpu_to_le16(pad_len); 736 + ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc); 737 + dst += EXT4_FC_TAG_BASE_LEN; 738 + if (pad_len > 0) { 739 + ext4_fc_memzero(sb, dst, pad_len, crc); 740 + dst += pad_len; 741 + } 750 742 /* Don't leak uninitialized memory in the unused last byte. */ 751 - *((u8 *)(tl + 1) + pad_len) = 0; 743 + *dst = 0; 752 744 753 745 ext4_fc_submit_bh(sb, false); 754 746 ··· 760 748 sbi->s_fc_bh = bh; 761 749 sbi->s_fc_bytes = (sbi->s_fc_bytes / bsize + 1) * bsize + len; 762 750 return sbi->s_fc_bh->b_data; 763 - } 764 - 765 - /* memcpy to fc reserved space and update CRC */ 766 - static void *ext4_fc_memcpy(struct super_block *sb, void *dst, const void *src, 767 - int len, u32 *crc) 768 - { 769 - if (crc) 770 - *crc = ext4_chksum(EXT4_SB(sb), *crc, src, len); 771 - return memcpy(dst, src, len); 772 751 } 773 752 774 753 /*