Skip to content

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

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 17, 2025

Conversation

jainanmol84
Copy link

@jainanmol84 jainanmol84 commented Jul 17, 2025

  • 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-4776
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.config' -> '.config'
Setting Local Version for build
CONFIG_LOCALVERSION="-_ajain_ciqlts8_6-a2bddbb69"
Making olddefconfig
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  YACC    scripts/kconfig/zconf.tab.c
  LEX     scripts/kconfig/zconf.lex.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf  --olddefconfig Kconfig
#
# configuration written to .config
#
Starting Build
scripts/kconfig/conf  --syncconfig Kconfig
  SYSTBL  arch/x86/include/generated/asm/syscalls_32.h
  HOSTCC  scripts/basic/bin2c
  UPD     include/config/kernel.release
  WRAP    arch/x86/include/generated/uapi/asm/bpf_perf_event.h
  WRAP    arch/x86/include/generated/uapi/asm/poll.h
  WRAP    arch/x86/include/generated/uapi/asm/socket.h
  UPD     include/generated/uapi/linux/version.h
  UPD     include/generated/utsrelease.h
  DESCEND objtool
  HOSTCC  /home/anmol/kernel-src-tree/tools/objtool/fixdep.o
[--snip--]
  INSTALL sound/usb/snd-usb-audio.ko
  INSTALL sound/usb/snd-usbmidi-lib.ko
  INSTALL sound/usb/usx2y/snd-usb-us122l.ko
  INSTALL sound/usb/usx2y/snd-usb-usx2y.ko
  INSTALL sound/virtio/virtio_snd.ko
  INSTALL sound/x86/snd-hdmi-lpe-audio.ko
  INSTALL sound/xen/snd_xen_front.ko
  INSTALL virt/lib/irqbypass.ko
  DEPMOD  4.18.0-_ajain_ciqlts8_6-a2bddbb69+
[TIMER]{MODULES}: 21s
Making Install
sh ./arch/x86/boot/install.sh 4.18.0-_ajain_ciqlts8_6-a2bddbb69+ arch/x86/boot/bzImage \
	System.map "/boot"
[TIMER]{INSTALL}: 32s
Checking kABI
Checking kABI
kABI check passed
Setting Default Kernel to /boot/vmlinuz-4.18.0-_ajain_ciqlts8_6-a2bddbb69+ and Index to 25
The default is /boot/loader/entries/d1213ab044df421ca370e008adff1cf2-4.18.0-_ajain_ciqlts8_6-a2bddbb69+.conf with index 25 and kernel /boot/vmlinuz-4.18.0-_ajain_ciqlts8_6-a2bddbb69+
The default is /boot/loader/entries/d1213ab044df421ca370e008adff1cf2-4.18.0-_ajain_ciqlts8_6-a2bddbb69+.conf with index 25 and kernel /boot/vmlinuz-4.18.0-_ajain_ciqlts8_6-a2bddbb69+
Generating grub configuration file ...
done
Hopefully Grub2.0 took everything ... rebooting after time metrices
[TIMER]{MRPROPER}: 0s
[TIMER]{BUILD}: 3125s
[TIMER]{MODULES}: 21s
[TIMER]{INSTALL}: 32s
[TIMER]{TOTAL} 3182s
Rebooting in 10 seconds

kernel-build.log

Kselftests

$ grep '^ok ' kselftest-before.log | wc -l && grep '^ok ' kselftest-after.log | wc -l
196
196
$ grep '^not ok ' kselftest-before.log | wc -l && grep '^not ok ' kselftest-after.log | wc -l
51
51

kselftest-after.log
kselftest-before.log

jira VULN-4776
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 a5f217e into ciqlts8_6 Jul 17, 2025
2 checks passed
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