#1128829 patch: FTBFS with glibc 2.43 on arm64, issue with 2MB THP

Package:
src:patch
Source:
src:patch
Submitter:
Emanuele Rocca
Date:
2026-02-25 22:17:02 UTC
Severity:
normal
Tags:
#1128829#5
Date:
2026-02-23 12:44:16 UTC
From:
To:
Hi,

patch fails to build from source on arm64 when using glibc 2.43,
currently in experimental.

The issue is triggered by glibc 2.43 on arm64 enabling 2MB THP by
default:
https://sourceware.org/git/?p=glibc.git;a=commit;h=321e1fc73f53081d92ba357cdd48c56b79292020

The problem is however not architecture-specific. For example it can be
reproduced with glibc 2.42 on amd64 by building the package with the
GLIBC_TUNABLES environment variable set to glibc.malloc.hugetlb=2.

Successful build with glibc 2.42, currently in sid:
https://people.debian.org/~ema/glibc-2.43-rebuilds/output-2/patch_arm64.build

Logs of a failed build with glibc 2.43 are here:
https://people.debian.org/~ema/glibc-2.43-rebuilds/output-1/patch_arm64.build

Salient part:

FAIL: bad-filenames
===================

[27] emit_patch ../z | patch -f -p1 --dry-run || echo status: $? -- ok
[31] emit_patch /absolute/path | patch -f -p0 --dry-run || echo status: $? -- ok
[52] emit_patch $filename | (cd / && patch -f -p0 --dry-run) || echo status: $? -- ok
[56] emit_patch a/../z | patch -f -p0 --dry-run || echo status: $? -- ok
[70] emit_patch a/../z | patch -f -p1 --dry-run || echo status: $? -- ok
[84] emit_patch ../z | patch -f -p0 --dry-run || echo status: $? -- ok
[106] patch -f -p0 --dry-run < d.diff || echo status: $? -- ok
[120] patch -f -p0 --dry-run < d.diff || echo status: $? -- ok
[125] patch -f -p1 --dry-run < d.diff || echo status: $? -- ok
[134]
    emit_patch '"a\nb"' | patch   >patch.out 2>&1
    status=$?
    sed "$fixup" patch.out
    echo status: $status
   -- ok
[134]
    emit_patch 'foo' | patch 'a
b'  >patch.out 2>&1
    status=$?
    sed "$fixup" patch.out
    echo status: $status
   -- ok
[134]
    emit_patch 'foo' | patch '-o' 'a
b' >patch.out 2>&1
    status=$?
    sed "$fixup" patch.out
    echo status: $status
   -- ok
[175] emit_patch_with_NUL | patch; echo status: $? -- ok
[190] patch -f -p0 < d.diff || echo status: $? -- ok
[206] emit_patch f | patch -r- "" || echo status: $? -- FAILED
--- expected
+++ got
@@ -1,3 +1,3 @@
-File '' is not a regular file -- refusing to patch
-1 out of 1 hunk ignored
-status: 1
+patching file ''
+/build/reproducible-path/patch-2.8/src/patch: **** Can't rename file .o3yWHeL to '' : No such file or directory
+status: 2
15 tests (14 passed, 1 failed)
FAIL bad-filenames (exit status: 1)

#1128829#10
Date:
2026-02-25 22:14:26 UTC
From:
To:
Hi,

The issue is that the recent upstream change backported into
reject_empty_filenames.patch change safe_xstat() to return EINVAL in
case of an empty filename, but also assumes that errno is 0, so that the
error is later masked in stat_file(), returning 0 in that case. The
malloc() code change in glibc 2.43 can set in some conditions errno to
ENOENT even if the memory allocation is successful.

The patch below fixes that, although it should be checked by someone
with a deeper knowledge of the code. Intuitively I would have actually
set errno to EINVAL and changed the return to -1, but then that breaks
the testsuite the same way all the time, as stat_file() doesn't mask it
anymore.

diff --git a/src/safe.c b/src/safe.c
index 065c13b..9ce2ee7 100644
--- a/src/safe.c
+++ b/src/safe.c
@@ -572,7 +572,10 @@ safe_xstat (char *pathname, struct stat *buf, int flags)
   if (dirfd == DIRFD_INVALID)
     return -1;
   if (! strcmp (pathname, ""))
-    return EINVAL;
+    {
+      errno = 0;
+      return EINVAL;
+    }
   return fstatat (dirfd, pathname, buf, flags);
 }

Regards
Aurelien