Skip to content

[LTS 9.2] ext4: fix double-free of blocks due to wrong extents moved_len #426

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 19, 2025

Conversation

jainanmol84
Copy link

  • Commit Message Requirements
  • Built against Vault/LTS Environment
  • kABI Check Passed, where Valid (Pre 9.4 RT does not have kABI stability)
  • Boot Test
  • Kernel SelfTest results
  • Additional Tests as determined relevant

Commit message

jira VULN-4781
cve CVE-2024-26704
commit-author Baokun Li <[email protected]>
commit 55583e899a5357308274601364741a83e78d6ac4

In ext4_move_extents(), moved_len is only updated when all moves are successfully executed, and only discards orig_inode and donor_inode preallocations when moved_len is not zero. When the loop fails to exit after successfully moving some extents, moved_len is not updated and remains at 0, so it does not discard the preallocations.

If the moved extents overlap with the preallocated extents, the overlapped extents are freed twice in ext4_mb_release_inode_pa() and ext4_process_freed_data() (as described in commit 94d7c16cbbbd ("ext4: Fix double-free of blocks with EXT4_IOC_MOVE_EXT")), and bb_free is incremented twice. Hence when trim is executed, a zero-division bug is triggered in mb_update_avg_fragment_size() because bb_free is not zero and bb_fragments is zero.

Therefore, update move_len after each extent move to avoid the issue.

	Reported-by: Wei Chen <[email protected]>
	Reported-by: xingwei lee <[email protected]>
Closes: https://lore.kernel.org/r/CAO4mrferzqBUnCag8R3m2zf897ts9UEuhjFQGPtODT92rYyR2Q@mail.gmail.com Fixes: fcf6b1b729bc ("ext4: refactor ext4_move_extents code base") CC:  <[email protected]> # 3.18
	Signed-off-by: Baokun Li <[email protected]>
	Reviewed-by: Jan Kara <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
	Signed-off-by: Theodore Ts'o <[email protected]>
(cherry picked from commit 55583e899a5357308274601364741a83e78d6ac4)
	Signed-off-by: Anmol Jain <[email protected]>

Kernel build logs

/home/anmol/kernel-src-tree
no .config file found, moving on
[TIMER]{MRPROPER}: 0s
x86_64 architecture detected, copying config
'configs/kernel-x86_64-rhel.config' -> '.config'
Setting Local Version for build
CONFIG_LOCALVERSION="-_ajain_ciqlts9_2-e69cb57e9"
Making olddefconfig
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/confdata.o
  HOSTCC  scripts/kconfig/expr.o
  LEX     scripts/kconfig/lexer.lex.c
  YACC    scripts/kconfig/parser.tab.[ch]
  HOSTCC  scripts/kconfig/lexer.lex.o
  HOSTCC  scripts/kconfig/menu.o
  HOSTCC  scripts/kconfig/parser.tab.o
  HOSTCC  scripts/kconfig/preprocess.o
  HOSTCC  scripts/kconfig/symbol.o
  HOSTCC  scripts/kconfig/util.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#
Starting Build
  SYSHDR  arch/x86/include/generated/uapi/asm/unistd_32.h
  SYSHDR  arch/x86/include/generated/uapi/asm/unistd_64.h
  WRAP    arch/x86/include/generated/uapi/asm/bpf_perf_event.h
  WRAP    arch/x86/include/generated/uapi/asm/errno.h
  WRAP    arch/x86/include/generated/uapi/asm/fcntl.h
  WRAP    arch/x86/include/generated/uapi/asm/ioctl.h
  WRAP    arch/x86/include/generated/uapi/asm/ioctls.h
  SYSHDR  arch/x86/include/generated/uapi/asm/unistd_x32.h
  WRAP    arch/x86/include/generated/uapi/asm/ipcbuf.h
  WRAP    arch/x86/include/generated/uapi/asm/param.h
  WRAP    arch/x86/include/generated/uapi/asm/poll.h
[--snip--]
  STRIP   /lib/modules/5.14.0-_ajain_ciqlts9_2-e69cb57e9+/kernel/sound/xen/snd_xen_front.ko
  INSTALL /lib/modules/5.14.0-_ajain_ciqlts9_2-e69cb57e9+/kernel/virt/lib/irqbypass.ko
  SIGN    /lib/modules/5.14.0-_ajain_ciqlts9_2-e69cb57e9+/kernel/sound/xen/snd_xen_front.ko
  STRIP   /lib/modules/5.14.0-_ajain_ciqlts9_2-e69cb57e9+/kernel/virt/lib/irqbypass.ko
  SIGN    /lib/modules/5.14.0-_ajain_ciqlts9_2-e69cb57e9+/kernel/virt/lib/irqbypass.ko
  DEPMOD  /lib/modules/5.14.0-_ajain_ciqlts9_2-e69cb57e9+
[TIMER]{MODULES}: 15s
Making Install
sh ./arch/x86/boot/install.sh \
        5.14.0-_ajain_ciqlts9_2-e69cb57e9+ arch/x86/boot/bzImage \
        System.map "/boot"
[TIMER]{INSTALL}: 37s
Checking kABI
Checking kABI
kABI check passed
Setting Default Kernel to /boot/vmlinuz-5.14.0-_ajain_ciqlts9_2-e69cb57e9+ and Index to 3
The default is /boot/loader/entries/65b5ae363fe94129b0075258ce5a010a-5.14.0-_ajain_ciqlts9_2-e69cb57e9+.conf with index 3 and kernel /boot/vmlinuz-5.14.0-_ajain_ciqlts9_2-e69cb57e9+
The default is /boot/loader/entries/65b5ae363fe94129b0075258ce5a010a-5.14.0-_ajain_ciqlts9_2-e69cb57e9+.conf with index 3 and kernel /boot/vmlinuz-5.14.0-_ajain_ciqlts9_2-e69cb57e9+
Generating grub configuration file ...
Adding boot menu entry for UEFI Firmware Settings ...
done
Hopefully Grub2.0 took everything ... rebooting after time metrices
[TIMER]{MRPROPER}: 0s
[TIMER]{BUILD}: 2915s
[TIMER]{MODULES}: 15s
[TIMER]{INSTALL}: 37s
[TIMER]{TOTAL} 2971s
Rebooting in 10 seconds

kernel-build.log

Kselftests

$ grep '^ok ' kselftest-before.log | wc -l && grep '^ok ' kselftest-after.log | wc -l
318
319
$ grep '^not ok ' kselftest-before.log | wc -l && grep '^not ok ' kselftest-after.log | wc -l
66
65

kselftest-after.log
kselftest-before.log

jira VULN-4781
cve CVE-2024-26704
commit-author Baokun Li <[email protected]>
commit 55583e8

In ext4_move_extents(), moved_len is only updated when all moves are
successfully executed, and only discards orig_inode and donor_inode
preallocations when moved_len is not zero. When the loop fails to exit
after successfully moving some extents, moved_len is not updated and
remains at 0, so it does not discard the preallocations.

If the moved extents overlap with the preallocated extents, the
overlapped extents are freed twice in ext4_mb_release_inode_pa() and
ext4_process_freed_data() (as described in commit 94d7c16 ("ext4:
Fix double-free of blocks with EXT4_IOC_MOVE_EXT")), and bb_free is
incremented twice. Hence when trim is executed, a zero-division bug is
triggered in mb_update_avg_fragment_size() because bb_free is not zero
and bb_fragments is zero.

Therefore, update move_len after each extent move to avoid the issue.

	Reported-by: Wei Chen <[email protected]>
	Reported-by: xingwei lee <[email protected]>
Closes: https://lore.kernel.org/r/CAO4mrferzqBUnCag8R3m2zf897ts9UEuhjFQGPtODT92rYyR2Q@mail.gmail.com
Fixes: fcf6b1b ("ext4: refactor ext4_move_extents code base")
CC:  <[email protected]> # 3.18
	Signed-off-by: Baokun Li <[email protected]>
	Reviewed-by: Jan Kara <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
	Signed-off-by: Theodore Ts'o <[email protected]>
(cherry picked from commit 55583e8)
	Signed-off-by: Anmol Jain <[email protected]>
Copy link

@thefossguy-ciq thefossguy-ciq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚤

Copy link
Collaborator

@PlaidCat PlaidCat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@jainanmol84 jainanmol84 merged commit e656ea9 into ciqlts9_2 Jul 19, 2025
3 checks passed
@jainanmol84 jainanmol84 deleted the {ajain_ciqlts9_2 branch July 19, 2025 08:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants