From 19ddc627786162b553f8cfceff247e2fea68d1ca Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 25 Mar 2023 19:06:07 +0100 Subject: [PATCH] Fix undefined behaviour when writing 32-bit values in phar/tar.c As shown on the CI runs on my fork (which runs with UBSAN), the pointers can sometimes be unaligned when trying to write. This is UB and on platforms like ARM this *can* result in a bus error. Replace it with memcpy, which at least on x86 and powerpc architectures does result in the same assembly code. Closes GH-10940. --- ext/phar/tar.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 99b6b9812de..80a17d69318 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -1244,13 +1244,15 @@ nostub: return EOF; } #ifdef WORDS_BIGENDIAN -# define PHAR_SET_32(var, buffer) \ - *(uint32_t *)(var) = (((((unsigned char*)&(buffer))[3]) << 24) \ - | ((((unsigned char*)&(buffer))[2]) << 16) \ - | ((((unsigned char*)&(buffer))[1]) << 8) \ - | (((unsigned char*)&(buffer))[0])) +# define PHAR_SET_32(destination, source) do { \ + uint32_t swapped = (((((unsigned char*)&(source))[3]) << 24) \ + | ((((unsigned char*)&(source))[2]) << 16) \ + | ((((unsigned char*)&(source))[1]) << 8) \ + | (((unsigned char*)&(source))[0])); \ + memcpy(destination, &swapped, 4); \ + } while (0); #else -# define PHAR_SET_32(var, buffer) *(uint32_t *)(var) = (uint32_t) (buffer) +# define PHAR_SET_32(destination, source) memcpy(destination, &source, 4) #endif PHAR_SET_32(sigbuf, phar->sig_flags); PHAR_SET_32(sigbuf + 4, signature_length);