1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

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.
This commit is contained in:
Niels Dossche
2023-03-25 19:06:07 +01:00
parent 93e0f6b424
commit 19ddc62778

View File

@@ -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);