#1118023 xdelta3: Bus error on sparc64 in xd3_forward_match

Package:
xdelta3
Source:
xdelta3
Description:
Diff utility which works with binary files
Submitter:
Gregor Riepl
Date:
2025-10-19 13:41:01 UTC
Severity:
normal
#1118023#5
Date:
2025-10-13 21:46:24 UTC
From:
To:
In specific circumstances, xdelta3 produces a bus error on sparc64,
presumably because of unaligned memory access.

This makes the tool practically unusable on this architecture.

Example stack trace:

(gdb) run encode -0 -f -D -s fromfile tofile delta
Starting program: /usr/bin/xdelta3 encode -0 -f -D -s fromfile tofile delta
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/sparc64-linux-gnu/libthread_db.so.1".

Program received signal SIGBUS, Bus error.
0x000000000010ce60 in xd3_forward_match (n=9213, s2c=0x2306a3 "clude <stdio.h>\n\nint main(int argc, char** argv) {\n  return 0;\n}\n",
    s1c=0xfffff80100c10413 "clude <stdio.h>\n\nint main(int argc, char** argv) {\n  return 0;\n}\n") at xdelta3.c:3891
warning: 3891   xdelta3.c: No such file or directory
(gdb) bt
#0  0x000000000010ce60 in xd3_forward_match (n=9213, s2c=0x2306a3 "clude <stdio.h>\n\nint main(int argc, char** argv) {\n  return 0;\n}\n",
    s1c=0xfffff80100c10413 "clude <stdio.h>\n\nint main(int argc, char** argv) {\n  return 0;\n}\n") at xdelta3.c:3891
#1  xd3_source_extend_match (stream=stream@entry=0x7feffffe270) at xdelta3.c:4045
#2  0x000000000010dd98 in xd3_string_match_fastest (stream=0x7feffffe270) at xdelta3.c:4729
#3  0x000000000011105c in xd3_encode_input (stream=0x7feffffe270) at xdelta3.c:3226
#4  0x0000000000116ca4 in main_input (cmd=cmd@entry=CMD_ENCODE, ifile=ifile@entry=0x7feffffe800, ofile=ofile@entry=0x7feffffe860, sfile=sfile@entry=0x7feffffe8c0) at xdelta3-main.h:3201
#5  0x0000000000104fc8 in main (argc=<optimized out>, argv=<optimized out>) at xdelta3-main.h:3912

The test files are attached, they originate from the pristine-tar build process.

#1118023#10
Date:
2025-10-14 07:16:43 UTC
From:
To:
Hi Gregor,

This should be reported upstream, see:

https://github.com/jmacd/xdelta/issues

The testsuite also fails with unaligned access:

https://buildd.debian.org/status/fetch.php?pkg=xdelta3&arch=sparc64&ver=3.0.11-dfsg-1.2&stamp=1757507449&raw=0

I can file the bug report.

Adrian

#1118023#15
Date:
2025-10-14 08:46:37 UTC
From:
To:
Hi Adrian,

That would be much appreciated, thanks!

Interestingly, xdelta3 already contains code to detect and account for unaligned memory access. There's an m4 script that's supposed to do the detection (m4/ax_check_aligned_access_required.m4), but it seems like it's not doing its job correctly.

By putting the following into debian/rules, the script can be bypassed:

override_dh_auto_configure:
         dh_auto_configure $@ -- ax_cv_have_aligned_access_required=yes

This makes the bus error go away. The pristine-tar build is still failing, but this might have other reasons.

Regards,
Gregor

#1118023#20
Date:
2025-10-14 08:55:38 UTC
From:
To:
Hi Gregor,

I looked at upstream and the project seems to be dead, no changes since 2016.

Interesting, so it might not be broken at all?

You mean the unpatched source?

Adrian

#1118023#25
Date:
2025-10-14 10:30:20 UTC
From:
To:
That's bad, considering that xdelta3 is a dependency of pristine-tar. :/

I cleaned up the debugging code I had added to pristine-tar, installed the xdelta3 built with aligned access enforcement, and now the pristine-tar build finishes successfully.

Oh, and I just found out that the ax_check_aligned_access_required detection script will "hide" the unaligned memory access crash if it's compiled with optimization. When using -O0, it will crash with a bus error on sparc64, as it should.
It's the same with a more recent version of the script[1].

So, IMHO the cleanest fix should be to compile test script without optimization, to ensure it's causing a bus error and correctly detect that the target cpu requires aligned memory access.

Sorry, which patch are you referring to?
Except for the override of the check, I didn't patch anything.

[1] https://gitweb.git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_check_aligned_access_required.m4

#1118023#30
Date:
2025-10-14 11:04:50 UTC
From:
To:
That was not obvious to me when you wrote this.

Good.

OK, so the code remains broken.

Well, the bus error is well visible when running the xdelta3 testsuite.

The xdelta3 package has two patches, but they don't patch any C code as I just saw:

https://salsa.debian.org/debian/xdelta3/-/tree/master/debian/patches?ref_type=heads

But this was also a misunderstanding from my side. Since "pristine-tar" also refers
to a Git branch when maintaining package sources with Git, I thought you were referring
to the vanilla upstream source.

It was not clear to me that you were talking about the "pristine-tar" Debian package.


Adrian

#1118023#35
Date:
2025-10-14 11:36:29 UTC
From:
To:
I was really referring to the Debian tool "pristine-tar" for managing pristine-tar branches.
The reason I stumbled upon the problem in the first place was that the latest version was mysteriously absent from the repos, which led to discovering this: https://buildd.debian.org/status/package.php?p=pristine-tar#problem-2

And that in turn is caused by xdelta3.

#1118023#40
Date:
2025-10-14 17:16:05 UTC
From:
To:
Well, the bus error in xdelta3 itself yes... but I was referring to the autconf check.
This one _doesn't_ cause a bus error (as it should), when it's compiled with optimization.
If it was, configure could detect it and and automatically set ax_cv_have_aligned_access_required=yes - which will then set a macro that disables all the code that causes unaligned access.

If the autoconf check script is compiled with -O0, it will cause a bus error, which is what I suggested as a solution. I'm not sure how to fix this script so it will trigger the bus error even with -Os or -O3.

The rest of xdelta3 can be compiled with -O3/-Os just fine, as long as the macro is set.

#1118023#45
Date:
2025-10-14 17:24:23 UTC
From:
To:
Does that mean that the unaligned access is intentional? Why is there an option to disable it?

I'm not sure I'm following. Does the code actually trap SIGBUS to determine whether there was
an unaligned access and the SIGBUS does not occir with -O0?

And the testsuite passes as well?

Adrian

#1118023#50
Date:
2025-10-14 18:59:49 UTC
From:
To:
Apparently, there are other architectures that had alignment issues in the past, so they added code to xdelta3 that works without unaligned access. There are guard #ifdefs around the unaligned code. Example: [1]

Then, there is this autoconf macro[2] they use to detect if the target requires aligned access.
This script does not actually trigger bus errors, but it's meant to detect if the lower address bits are ignored on non-byte-aligned memory access.
However, my assumption is that it will also work if the test program crashes with a bus error.

If that's not the case, a different solution needs to be found, such as hardcoding ax_cv_have_aligned_access_required=yes when the CPU architecture is sparc or sparc64.
Yes, at least the autopkgtest that is run when building the package.
Same for pristine-tar, with the xdelta3 that is built this way.

[1] https://salsa.debian.org/debian/xdelta3/-/blob/master/xdelta3.c#L3881
[2] https://salsa.debian.org/debian/xdelta3/-/blob/master/m4/ax_check_aligned_access_required.m4

#1118023#55
Date:
2025-10-14 19:25:31 UTC
From:
To:
OK, after looking at the code, I understand the situation now. Thanks for the clarification.

That's not really important. What is important is figuring out how to patch the m4 script that
it works properly. In fact, this particular script is also part of texlive-bin [1] and the test
there works correctly [2]:

checking size of int... 4
checking size of long... (cached) 8
checking whether byte ordering is bigendian... yes
checking if pointers to integers require aligned access... yes
checking for strcasecmp... yes
checking for strnlen... yes
checking for strndup... yes

Look at the version of the script from [1], it has a hard-coded list for cross-compiling:

AC_DEFUN([AX_CHECK_ALIGNED_ACCESS_REQUIRED],
[AC_CACHE_CHECK([if pointers to integers require aligned access],
  [ax_cv_have_aligned_access_required],
[if test "$cross_compiling" = "yes"; then
  case "$host_cpu" in alpha*|arm*|bfin*|hp*|mips*|sh*|sparc*|ia64|nv1)
    ax_cv_have_aligned_access_required="yes"
  ;; esac

I suggest you try the version of the script from there and report back.

Adrian

#1118023#60
Date:
2025-10-15 21:35:16 UTC
From:
To:
Hi Adrian,


That script won't work out of the box because we're not cross-compiling. But, I added a little something to force aligned access when compiling on sparc. A patch against xdelta3 source is attached at the end. I didn't know about the other architectures, so I didn't touch them.

This does the trick on sparc64 - detection is now circumvented and the result is always yes, and I also did a quick check on amd64, to make sure it doesn't trigger.

Regards,
Gregor


diff --git a/m4/ax_check_aligned_access_required.m4 b/m4/ax_check_aligned_access_required.m4
index b078275..7118531 100644
--- a/m4/ax_check_aligned_access_required.m4
+++ b/m4/ax_check_aligned_access_required.m4
@@ -54,7 +54,19 @@
   AC_DEFUN([AX_CHECK_ALIGNED_ACCESS_REQUIRED],
   [AC_CACHE_CHECK([if pointers to integers require aligned access],
     [ax_cv_have_aligned_access_required],
-  [AC_TRY_RUN([
+  [if test "$cross_compiling" = "yes"; then
+  case "$host_cpu" in alpha*|arm*|bfin*|hp*|mips*|sh*|sparc*|ia64|nv1)
+    ax_cv_have_aligned_access_required="yes"
+  ;; esac
+else
+  case "$host_cpu" in
+    sparc*)
+      # these architectures always require aligned memory access
+      # and detection by programmatic means is not reliable
+      ax_cv_have_aligned_access_required="yes"
+    ;;
+    *)
+  AC_TRY_RUN([
   #include <stdio.h>
   #include <stdlib.h>

@@ -77,6 +89,9 @@ int main()
        [ax_cv_have_aligned_access_required=no],
        [ax_cv_have_aligned_access_required=no])
     ])
+    ;;
+  esac
+fi
   if test "$ax_cv_have_aligned_access_required" = yes ; then
     AC_DEFINE([HAVE_ALIGNED_ACCESS_REQUIRED], [1],
       [Define if pointers to integers require aligned access])

#1118023#65
Date:
2025-10-15 22:50:27 UTC
From:
To:
Hello,

But obviously works correctly in the texlive-bin package as could be seen from the build log I posted.

What’s the difference?

Adrian

#1118023#70
Date:
2025-10-19 12:09:19 UTC
From:
To:
That doesn't make a lot of sense...
If you're not cross-compiling, why would $cross_compiling be set and the case statement be executed?

But, I gave it the benefit of the doubt, replaced the script with [1], and the result was that configure bailed out with a syntax error. Looking at the script, it's clear that the "fi" on line 59 is in the wrong place. It should be on line 58, as it belongs to the if/else on line 31 and 35. The ]) on line 58 belongs to the AC_CACHE_CHECK on line 29.

I'm not sure how this script is supposed to work for texlive-bin, but it's obviously broken.

#1118023#75
Date:
2025-10-19 12:20:23 UTC
From:
To:
Hi Gregor,

Thanks for verifying this. Looking closer at the texlive-bin package, it actually contains a
large patch which modifies the zziplib package, see:

https://sources.debian.org/src/texlive-bin/2025.20250727.75242%2Bds-4/debian/patches/zziplib.diff

I have extracted the zziplib-aligned-access.m4 m4 script from there and I'm attaching it.

Can you give it a try?

Adrian

#1118023#80
Date:
2025-10-19 13:29:56 UTC
From:
To:
This looks more promising, but still no dice (after renaming ZZIPLIB_CHECK_ALIGNED_ACCESS to AX_CHECK_ALIGNED_ACCESS_REQUIRED):

checking if pointers to integers require aligned access... no

I guess that makes sense, the fourth argument of AC_RUN_IFELSE() will only execute when cross compiling[1].
While the script is certainly cleaner this way, it will still fail for cases where the test script can't detect the alignment behavior of the host CPU.

I really think the only fix here is to skip the AC_RUN_IFELSE for CPU types that are known to always require aligned access (such as sparc and sparc64). Or write a better test program that works on sparc.

[1] https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.72/html_node/Runtime.html

#1118023#85
Date:
2025-10-19 13:39:52 UTC
From:
To:
Hi Gregor,

OK, I'll have a look myself. I mean, if it works for texlive-bin, I don't see why it shouldn't work
for xdelta3. I want to avoid hacking a custom solution when there is a commonly adopted m4 script.

Adrian