From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
patches@lists.linux.dev, Jan Kara <jack@suse.cz>,
Zhang Yi <yi.zhang@huawei.com>, Theodore Tso <tytso@mit.edu>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 7.1 13/76] ext4: protect WRITE_ZEROES written extents with orphan list
Date: Mon, 31 Aug 2026 15:33:45 +0200 [thread overview]
Message-ID: <20260831133359.864129005@linuxfoundation.org> (raw)
In-Reply-To: <20260831133359.185608553@linuxfoundation.org>
7.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Yi <yi.zhang@huawei.com>
[ Upstream commit f7237a775c8f3e99e0e77b7c10fb626815fb2877 ]
In ext4_alloc_file_blocks(), the WRITE_ZEROES path converts unwritten
extents to written in one transaction, while i_disksize is updated to
cover them only in a later transaction. A crash in between leaves
written extents beyond i_disksize on disk, which fsck will complain
about.
To fix this, add the inode to the orphan list in the same handle that
does the conversion, and remove it once i_disksize has caught up.
Also add a sanity check to ensure conversion does not extend beyond EOF.
Since ext4_alloc_file_blocks() is called from the fallocate() path,
partial allocation is safe. On partial conversion failure, advance
i_disksize only up to the boundary of successfully converted blocks, so
that orphan cleanup sees a consistent state. Document this behavior in
the function comment.
Reported-by: Jan Kara <jack@suse.cz>
Closes: https://lore.kernel.org/linux-ext4/3f6ao5amv7glbgigndtegcucgo3n34ij3lau6l3da3hgdxgn3v@ev66wv3r5umt/
Fixes: f4265b8d32c4 ("ext4: add FALLOC_FL_WRITE_ZEROES support")
Cc: stable@vger.kernel.org
Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260729085918.3336221-3-yi.zhang@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/ext4/extents.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 69 insertions(+), 7 deletions(-)
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4571,6 +4571,22 @@ retry_remove_space:
return err;
}
+/*
+ * Pre-allocate blocks for the range [@offset, @offset + @len). Allocated
+ * blocks are marked as unwritten by default. If EXT4_GET_BLOCKS_ZERO is
+ * set, the allocated blocks are zeroed on disk and their extents are
+ * converted to written state.
+ *
+ * When @new_size is nonzero, the caller intends to extend the file, and
+ * the file size should be updated to the end of the allocated blocks.
+ *
+ * Allocation may partially succeed due to some non-fatal issues. In that
+ * case, i_disksize (and i_size) is advanced up to the successfully
+ * processed portion of the range.
+ *
+ * Return 0 on success, or a negative error code on failure or partial
+ * failure.
+ */
static int ext4_alloc_file_blocks(struct file *file, loff_t offset, loff_t len,
loff_t new_size, int flags)
{
@@ -4585,6 +4601,7 @@ static int ext4_alloc_file_blocks(struct
loff_t epos = 0, old_size = i_size_read(inode);
unsigned int blkbits = inode->i_blkbits;
bool alloc_zero = false;
+ bool orphan = false;
BUG_ON(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS));
map.m_lblk = offset >> blkbits;
@@ -4659,19 +4676,49 @@ retry:
if (alloc_zero &&
(map.m_flags & (EXT4_MAP_MAPPED | EXT4_MAP_UNWRITTEN))) {
+ ext4_lblk_t converted;
+
+ WARN_ON_ONCE(map.m_lblk + map.m_len >
+ EXT4_B_TO_LBLK(inode, new_size ?: old_size));
+
ret = ext4_issue_zeroout(inode, map.m_lblk, map.m_pblk,
map.m_len);
- if (likely(!ret))
- ret = ext4_convert_unwritten_extents(NULL,
+ if (unlikely(ret))
+ break;
+
+ handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS,
+ credits);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ break;
+ }
+
+ ret = ext4_convert_unwritten_extents(handle,
inode, (loff_t)map.m_lblk << blkbits,
- (loff_t)map.m_len << blkbits, NULL);
+ (loff_t)map.m_len << blkbits,
+ &converted);
if (ret)
- break;
+ map.m_len = converted;
+
+ /*
+ * If blocks beyond i_disksize are converted, add
+ * the inode to the orphan list and advance the epos.
+ */
+ if (new_size && converted) {
+ ret2 = ext4_orphan_add(handle, inode);
+ ret = ret ? ret : ret2;
+ orphan = true;
+ }
+
+ ret3 = ext4_journal_stop(handle);
+ ret = ret ? ret : ret3;
}
map.m_lblk += map.m_len;
map.m_len = len_lblk = len_lblk - map.m_len;
epos = EXT4_LBLK_TO_B(inode, map.m_lblk);
+ if (ret)
+ break;
}
if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
@@ -4687,11 +4734,23 @@ retry:
if (epos > new_size)
epos = new_size;
- handle = ext4_journal_start(inode, EXT4_HT_MISC, 1);
- if (IS_ERR(handle))
- return ret ? ret : PTR_ERR(handle);
+ handle = ext4_journal_start(inode, EXT4_HT_MISC, 2);
+ if (IS_ERR(handle)) {
+ /*
+ * The conversion has successfully completed. Not much to
+ * do with the error here so just cleanup the orphan list
+ * and hope for the best.
+ */
+ if (orphan && inode->i_nlink)
+ ext4_orphan_del(NULL, inode);
+ ret2 = PTR_ERR(handle);
+ goto out;
+ }
ext4_update_inode_size(inode, epos);
+ if (orphan && inode->i_nlink)
+ ext4_orphan_del(handle, inode);
+
ret2 = ext4_mark_inode_dirty(handle, inode);
ext4_update_inode_fsync_trans(handle, inode, 1);
ret3 = ext4_journal_stop(handle);
@@ -4699,6 +4758,9 @@ retry:
if (epos > old_size)
pagecache_isize_extended(inode, old_size, epos);
+out:
+ if (ret2)
+ ext4_std_error(inode->i_sb, ret2);
return ret ? ret : ret2;
}
next prev parent reply other threads:[~2026-08-31 13:41 UTC|newest]
Thread overview: 85+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 13:33 [PATCH 7.1 00/76] 7.1.13-rc1 review Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 01/76] bpf: reject overlarge global subprog argument sizes Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 02/76] RDMA/rxe: Fix responder UAF on IB_QP_MAX_DEST_RD_ATOMIC modify_qp Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 03/76] RDMA/rxe: Fix OOB in free_rd_atomic_resources() Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 04/76] KVM: x86/mmu: Check write tracking in all address spaces Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 05/76] nvme-tcp: fix usage of page_frag_cache Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 06/76] Revert "selinux: reject a permission value exceeding the class permission count" Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 07/76] selinux: use u16 for security classes Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 08/76] selinux: more strict policy parsing Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 09/76] selinux: reject a permission value exceeding the class permission count Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 10/76] selinux: require a classs permission values to cover its " Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 11/76] selinux: switch two allocations to use kzalloc_objs() Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 12/76] ext4: export converted block count from ext4_convert_unwritten_extents() Greg Kroah-Hartman
2026-08-31 13:33 ` Greg Kroah-Hartman [this message]
2026-08-31 13:33 ` [PATCH 7.1 14/76] ext4: move partial block zeroing earlier in ext4_zero_range() Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 15/76] ext4: write back partial-zeroed edges in WRITE_ZEROES Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 16/76] ext4: track partial-zero outcome per edge in ext4_zero_partial_blocks() Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 17/76] ext4: zero out whole block for clean edges in WRITE_ZEROES Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 18/76] fpga: dfl: fme: add error handling Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 19/76] accessibility: speakup: unregister tty ldisc on later init failures Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 20/76] usb: xhci: Handle bogus TRB pointers in Missed Service Error events Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 21/76] usb: xhci: Handle USB3 port events when there is one roothub Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 22/76] usb: xhci: bail out of setup if the controller is inaccessible Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 23/76] xhci: dbgtty: Fix unregister on tty_register_driver() failure Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 24/76] xhci: dbgtty: Fix unregister on tty_alloc_driver() failure Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 25/76] fuse: fix invalidate lock leak on setattr writeback failure Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 26/76] fuse: fix invalidate lock leak on open O_TRUNC DAX failure Greg Kroah-Hartman
2026-08-31 13:33 ` [PATCH 7.1 27/76] usb: usbtest: disable dynamic ID support Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 28/76] usb: gadget: f_tcm: keep port count until LUN teardown completes Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 29/76] KVM: SEV: Drop FOLL_WRITE for encrypted region registration Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 30/76] KVM: SEV: Track the GPA of the guest-controlled VMSA used for SNP guests Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 31/76] KVM: SEV: Extract loading of guest-provided VMSA to a separate helper Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 32/76] KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is unusable Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 33/76] KVM: SEV: Wire up kvm_x86_ops.gmem_xxx() if and only if CONFIG_KVM_AMD_SEV=y Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 34/76] tls: device: fix out-of-bounds write in tls_append_frag() Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 35/76] gtp: serialize PDP context updates Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 36/76] net/tcp: fix TCP-AO key deletion in VRFs Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 37/76] tcp: fix AO info use-after-free in tcp_ao_connect_init() Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 38/76] net/tcp-ao: fix use-after-free of current_key on reconnect to another peer Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 39/76] net: advertise TCP MSS from the configured MTU, not the learned PMTU Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 40/76] xfrm: espintcp: fix UAF during close Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 41/76] tcp: clamp route advmss to TCP_MIN_MSS Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 42/76] xfrm: drop ESP-in-TCP packets with no ingress device Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 43/76] xfrm: avoid lock inversion in nat keepalive work Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 44/76] xfrm: ah6: validate routing header segments_left Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 45/76] xfrm: fix xfrm_state_construct() auth-trunc leak Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 46/76] xfrm: bound nat keepalive state collection Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 47/76] net: bridge: mcast: fix use-after-free of a master VLANs multicast context Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 48/76] net/packet: defer vmalloc TX_RING free until skbs finish Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 49/76] ipv6: seg6: clear IPv4 control block on IPIP decapsulation Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 50/76] batman-adv: reject unrepresentable multicast TVLV offsets Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 51/76] vxlan: keep the last remote linked during FDB flush Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 52/76] netfilter: nft_set_pipapo_avx2: add missing vzeroupper Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 53/76] netfilter: nf_tables: dont queue packet path object notifications Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 54/76] mm/swap: reject swapon() on filesystem-level encrypted files Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 55/76] kunit: irq: Continue increasing hrtimer interval for longer Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 56/76] crypto: virtio - bound the akcipher result length Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 57/76] crypto: qcom-rng - Enable clock in hwrng case Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 58/76] crypto: qcom-rng - Remove crypto_rng interface Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 59/76] crypto: qcom-rng - Allow zero as a random number Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 60/76] crypto: atmel-tdes - use scatterlist length before DMA mapping Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 61/76] crypto: krb5 - use kfree_sensitive() for derived key buffers Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 62/76] crypto: qce - fix CCM AAD buffer underallocation Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 63/76] crypto: iaa - fall back to software for multi-entry scatterlists Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 64/76] crypto: mxs-dcp - fix source scatterlist length access Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 65/76] crypto: qce - Remove unsafe/deprecated algorithms Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 66/76] KVM: s390: vsie: zero stale crypto bits Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 67/76] usb: core: Add lock to usb_wakeup_notification() Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 68/76] usb: core: Strengthen error handling in hub_hub_status() Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 69/76] ALSA: usb-audio: Fix sample rates for PreSonus AudioBox USB Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 70/76] ALSA: usb-audio: fix OOB write in snd_usbmidi_novation_output() Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 71/76] ALSA: usb-audio: Complete cleanup after system-resume errors Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 72/76] USB: serial: option: fix slab OOB read in interrupt URB callback Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 73/76] USB: serial: spcp8x5: drop broken carrier detect support Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 74/76] USB: c67x00: fix use-after-free in c67x00_add_iso_urb() Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 75/76] wifi: mt76: mt7925: ensure tx headroom in usb_sdio_tx_prepare_skb Greg Kroah-Hartman
2026-08-31 13:34 ` [PATCH 7.1 76/76] usb: usbfs: fix use-after-free of usb_device in usbdev_release() Greg Kroah-Hartman
2026-08-31 19:12 ` [PATCH 7.1 00/76] 7.1.13-rc1 review Brett A C Sheffield
2026-09-01 0:45 ` Florian Fainelli
2026-09-01 7:44 ` Barry K. Nathan
2026-09-01 8:42 ` Pavel Machek
2026-09-01 12:06 ` Peter Schneider
2026-09-01 16:44 ` Shuah Khan
2026-09-01 22:59 ` Ron Economos
2026-09-02 1:55 ` Justin Forbes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260831133359.864129005@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=jack@suse.cz \
--cc=patches@lists.linux.dev \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
--cc=tytso@mit.edu \
--cc=yi.zhang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox