From: Paul Barker <paul@pbarker.dev>
To: openembedded-core@lists.openembedded.org
Cc: Paul Barker <paul@pbarker.dev>
Subject: [PATCH] coreutils: Backport fix for lseek_copy loop
Date: Wed, 21 Jan 2026 10:41:11 +0000 [thread overview]
Message-ID: <20260121-fix-coreutils-v1-1-30a1769b5733@pbarker.dev> (raw)
We've seen intermittent failures on the autobuilder related to creating
hddimg images after updating to coreutils 9.9. The error message seen
is:
install: cannot lseek '.../core-image-minimal/1.0/sources/core-image-minimal-1.0/hddimg/rootfs.img': Invalid argument
This corresponds to an invalid argument passed to lseek() in the
create_hole() function in src/copy-file-data.c in coreutils. This in
turn is being given bad arguments due to incorrect handling of loop
variables in lseek_copy().
The upstream bug report [1] refers to an infinite loop, which isn't
quite what we're seeing, but the cause is likely the same. So, we're
applying the upstream fixes.
[1]: https://github.com/coreutils/coreutils/issues/159
[YOCTO #16120]
Signed-off-by: Paul Barker <paul@pbarker.dev>
---
I've tested this several times on the autobuilder via oe-selftest-debian
& oe-selftest-fedora and not hit the lseek error :)
---
.../coreutils/0001-fix-lseek-copy-loop.patch | 35 +++++++++++++
.../coreutils/0002-fix-lseek-copy-loop.patch | 58 ++++++++++++++++++++++
meta/recipes-core/coreutils/coreutils_9.9.bb | 2 +
3 files changed, 95 insertions(+)
diff --git a/meta/recipes-core/coreutils/coreutils/0001-fix-lseek-copy-loop.patch b/meta/recipes-core/coreutils/coreutils/0001-fix-lseek-copy-loop.patch
new file mode 100644
index 000000000000..75286dc43cb9
--- /dev/null
+++ b/meta/recipes-core/coreutils/coreutils/0001-fix-lseek-copy-loop.patch
@@ -0,0 +1,35 @@
+From bd528f923482223649aa84be7d131e69356149da Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
+Date: Sun, 4 Jan 2026 12:45:46 +0000
+Subject: [PATCH] copy: fix possible infinite loop with SEEK_HOLE
+
+Commit v9.8-95-g4c0cf3864 intended to initialize
+ext_start to src_pos, as was described at:
+https://lists.gnu.org/r/coreutils/2025-11/msg00035.html
+However ipos was inadvertently used, which is only
+valid the first time through the loop.
+
+* src/copy-file-data.c (lseek_copy): Use scan_inference->hole_start
+only with the initial offset passed to lseek_copy().
+* NEWS: Mention the bug fix.
+Reported at https://github.com/coreutils/coreutils/issues/159
+
+Upstream-Status: Backport (commit bd528f923482223649aa84be7d131e69356149da)
+ - Removed changes to NEWS as they don't apply.
+
+Signed-off-by: Paul Barker <paul@pbarker.dev>
+---
+
+diff --git a/src/copy-file-data.c b/src/copy-file-data.c
+index 927a6e0480..56b669fe72 100644
+--- a/src/copy-file-data.c
++++ b/src/copy-file-data.c
+@@ -338,7 +338,7 @@ lseek_copy (int src_fd, int dest_fd, char **abuf, idx_t buf_size,
+ for (off_t ext_start = scan_inference->ext_start;
+ 0 <= ext_start && ext_start < max_ipos; )
+ {
+- off_t ext_end = (ext_start == ipos
++ off_t ext_end = (ext_start == src_pos
+ ? scan_inference->hole_start
+ : lseek (src_fd, ext_start, SEEK_HOLE));
+ if (0 <= ext_end)
diff --git a/meta/recipes-core/coreutils/coreutils/0002-fix-lseek-copy-loop.patch b/meta/recipes-core/coreutils/coreutils/0002-fix-lseek-copy-loop.patch
new file mode 100644
index 000000000000..412c4835387a
--- /dev/null
+++ b/meta/recipes-core/coreutils/coreutils/0002-fix-lseek-copy-loop.patch
@@ -0,0 +1,58 @@
+From 33bc44e1ba3aa4c70f3cd16aa9c41331543986dd Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
+Date: Mon, 5 Jan 2026 14:46:33 +0000
+Subject: [PATCH] copy: protect against infinite loop due to pathological race
+
+Consider:
+
+1. In infer_scantype():
+ - SEEK_DATA returns 0
+ - hole punched at 0
+ - SEEK_HOLE returns 0 (now a hole)
+ - Cache scan_inference->hole_start = 0
+2. In lseek_copy():
+ - data written at 0
+ - ext_start = 0, use cached hole_start = 0
+ - ext_len = 0
+ - now loop doesn't progress
+
+* src/copy-file-data.c (lseek_copy): Apply a more defensive check
+to ensure we only use the cached offsets in SCAN_INFERENCE once.
+This protects against an infinite loop where an extent (at SRC_POS)
+flip flops between data and hole extent while infer_scantype()
+and lseek_copy() are inspecting it. I.e. ensure we use SEEK_HOLE
+to progress the copy.
+
+Upstream-Status: Backport (commit 33bc44e1ba3aa4c70f3cd16aa9c41331543986dd)
+Signed-off-by: Paul Barker <paul@pbarker.dev>
+---
+ src/copy-file-data.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/src/copy-file-data.c b/src/copy-file-data.c
+index 56b669fe72..9bc4311af4 100644
+--- a/src/copy-file-data.c
++++ b/src/copy-file-data.c
+@@ -335,12 +335,19 @@ lseek_copy (int src_fd, int dest_fd, char **abuf, idx_t buf_size,
+
+ debug->sparse_detection = COPY_DEBUG_EXTERNAL;
+
++ bool used_scan_inference = false;
++
+ for (off_t ext_start = scan_inference->ext_start;
+ 0 <= ext_start && ext_start < max_ipos; )
+ {
+- off_t ext_end = (ext_start == src_pos
+- ? scan_inference->hole_start
+- : lseek (src_fd, ext_start, SEEK_HOLE));
++ off_t ext_end;
++ if (ext_start == src_pos && ! used_scan_inference)
++ {
++ ext_end = scan_inference->hole_start;
++ used_scan_inference = true;
++ }
++ else
++ ext_end = lseek (src_fd, ext_start, SEEK_HOLE);
+ if (0 <= ext_end)
+ ext_end = MIN (ext_end, max_ipos);
+ else
diff --git a/meta/recipes-core/coreutils/coreutils_9.9.bb b/meta/recipes-core/coreutils/coreutils_9.9.bb
index cded545efb2c..7deadded062a 100644
--- a/meta/recipes-core/coreutils/coreutils_9.9.bb
+++ b/meta/recipes-core/coreutils/coreutils_9.9.bb
@@ -15,6 +15,8 @@ inherit autotools gettext texinfo
SRC_URI = "${GNU_MIRROR}/coreutils/${BP}.tar.xz \
file://remove-usr-local-lib-from-m4.patch \
+ file://0001-fix-lseek-copy-loop.patch \
+ file://0002-fix-lseek-copy-loop.patch \
file://run-ptest \
"
SRC_URI[sha256sum] = "19bcb6ca867183c57d77155eae946c5eced88183143b45ca51ad7d26c628ca75"
---
base-commit: c6e2bfc538258086053a569c2143ad8bc9a840bd
change-id: 20260120-fix-coreutils-edb9f37fe599
Best regards,
--
Paul Barker
next reply other threads:[~2026-01-21 10:41 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-21 10:41 Paul Barker [this message]
2026-01-21 12:39 ` [OE-core] [PATCH] coreutils: Backport fix for lseek_copy loop Antonin Godard
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=20260121-fix-coreutils-v1-1-30a1769b5733@pbarker.dev \
--to=paul@pbarker.dev \
--cc=openembedded-core@lists.openembedded.org \
/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