Source: pixman
Version: 0.46.4-1
Severity: important
Tags: patch upstream
User: [email protected]
Usertags: sparc64
X-Debbugs-Cc: [email protected]

Hello,

while running the pixman testsuite, the stress-test binary crashes on
sparc64 due to unaligned access [1]:

=================================== 27/35 ====================================
test:         stress-test
start time:   09:41:35
duration:     0.80s
result:       killed by signal 10 SIGBUS
command:      
UBSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1
 LD_LIBRARY_PATH=/build/reproducible-path/pixman-0.46.4/build/pixman 
MALLOC_PERTURB_=253 
MSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1
 MESON_TEST_ITERATION=1 
ASAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1 
/build/reproducible-path/pixman-0.46.4/build/test/stress-test
==============================================================================

There is an open pull request upstream which addresses this issue [2].

Please consider including this patch in the next upload.

Thanks,
Adrian

> [1] 
> https://buildd.debian.org/status/fetch.php?pkg=pixman&arch=sparc64&ver=0.46.4-1&stamp=1759138947&raw=0
> [2] https://gitlab.freedesktop.org/pixman/pixman/-/merge_requests/159

--
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913
>From 26611b3ecd1de7d06d90fa7512b6efaeaee7112d Mon Sep 17 00:00:00 2001
From: Matthieu Herrb <[email protected]>
Date: Fri, 1 Aug 2025 18:38:49 +0200
Subject: [PATCH 1/2] fix un-aligned uint64_t accesses on sparc64 triggered by
 stress-test

They happen with the a16b16g16r16 format that uses uint64_t pixels.
Not sure if it's the proper fix, nor why the test is triggering those.
Also one cannot use image accessors there, since they are limited to
32 bits.
---
 pixman/pixman-access.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 822bef6a..f8603112 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -725,7 +725,13 @@ fetch_scanline_a16b16g16r16_float (bits_image_t *  image,
 
     while (pixel < end)
     {
+#ifdef __sparc64__
+       uint64_t p;
+       if (((long long)pixel & 0x7LL) != 0) printf("xxxx\n");
+       memcpy(&p, pixel++, sizeof(p));
+#else
        uint64_t p = READ (image, pixel++);
+#endif
        uint64_t a = (p >> 48) & 0xffff;
        uint64_t b = (p >> 32) & 0xffff;
        uint64_t g = (p >> 16) & 0xffff;
@@ -943,7 +949,12 @@ fetch_pixel_a16b16g16r16_float (bits_image_t *image,
                                int           line)
 {
     uint64_t *bits = (uint64_t *)(image->bits + line * image->rowstride);
+#ifdef __sparc64__
+    uint64_t p;
+    memcpy(&p, bits+offset, sizeof(p));
+#else
     uint64_t p = READ (image, bits + offset);
+#endif
     uint64_t a = (p >> 48) & 0xffff;
     uint64_t b = (p >> 32) & 0xffff;
     uint64_t g = (p >> 16) & 0xffff;
@@ -1193,8 +1204,13 @@ store_scanline_a16b16g16r16_float (bits_image_t *  image,
        g = pixman_float_to_unorm (values[i].g, 16);
        b = pixman_float_to_unorm (values[i].b, 16);
 
+#ifdef __sparc64__
+       uint64_t p = (a << 48) | (b << 32) | (g << 16) | (r << 0) ;
+       memcpy(pixel++, &p, sizeof(uint64_t));
+#else
        WRITE (image, pixel++,
               (a << 48) | (b << 32) | (g << 16) | (r << 0));
+#endif
     }
 }
 
-- 
GitLab


>From 5bdde5517b73a419842809e1e776bd80227febf7 Mon Sep 17 00:00:00 2001
From: Matthieu Herrb <[email protected]>
Date: Sun, 3 Aug 2025 10:23:31 +0200
Subject: [PATCH 2/2] Remove the __sparc64__ conditional build.

On architectures with non strict alignment, the compiler will
optimize the memcpy() calls away.

While here also remove the debuging printf().
---
 pixman/pixman-access.c | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index f8603112..dcdf1b2b 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -725,13 +725,9 @@ fetch_scanline_a16b16g16r16_float (bits_image_t *  image,
 
     while (pixel < end)
     {
-#ifdef __sparc64__
        uint64_t p;
-       if (((long long)pixel & 0x7LL) != 0) printf("xxxx\n");
+
        memcpy(&p, pixel++, sizeof(p));
-#else
-       uint64_t p = READ (image, pixel++);
-#endif
        uint64_t a = (p >> 48) & 0xffff;
        uint64_t b = (p >> 32) & 0xffff;
        uint64_t g = (p >> 16) & 0xffff;
@@ -949,12 +945,8 @@ fetch_pixel_a16b16g16r16_float (bits_image_t *image,
                                int           line)
 {
     uint64_t *bits = (uint64_t *)(image->bits + line * image->rowstride);
-#ifdef __sparc64__
     uint64_t p;
     memcpy(&p, bits+offset, sizeof(p));
-#else
-    uint64_t p = READ (image, bits + offset);
-#endif
     uint64_t a = (p >> 48) & 0xffff;
     uint64_t b = (p >> 32) & 0xffff;
     uint64_t g = (p >> 16) & 0xffff;
@@ -1204,13 +1196,8 @@ store_scanline_a16b16g16r16_float (bits_image_t *  image,
        g = pixman_float_to_unorm (values[i].g, 16);
        b = pixman_float_to_unorm (values[i].b, 16);
 
-#ifdef __sparc64__
        uint64_t p = (a << 48) | (b << 32) | (g << 16) | (r << 0) ;
        memcpy(pixel++, &p, sizeof(uint64_t));
-#else
-       WRITE (image, pixel++,
-              (a << 48) | (b << 32) | (g << 16) | (r << 0));
-#endif
     }
 }
 
-- 
GitLab

Reply via email to