Skip to content

Commit 19ddc62

Browse files
committed
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.
1 parent 93e0f6b commit 19ddc62

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

ext/phar/tar.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,13 +1244,15 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int
12441244
return EOF;
12451245
}
12461246
#ifdef WORDS_BIGENDIAN
1247-
# define PHAR_SET_32(var, buffer) \
1248-
*(uint32_t *)(var) = (((((unsigned char*)&(buffer))[3]) << 24) \
1249-
| ((((unsigned char*)&(buffer))[2]) << 16) \
1250-
| ((((unsigned char*)&(buffer))[1]) << 8) \
1251-
| (((unsigned char*)&(buffer))[0]))
1247+
# define PHAR_SET_32(destination, source) do { \
1248+
uint32_t swapped = (((((unsigned char*)&(source))[3]) << 24) \
1249+
| ((((unsigned char*)&(source))[2]) << 16) \
1250+
| ((((unsigned char*)&(source))[1]) << 8) \
1251+
| (((unsigned char*)&(source))[0])); \
1252+
memcpy(destination, &swapped, 4); \
1253+
} while (0);
12521254
#else
1253-
# define PHAR_SET_32(var, buffer) *(uint32_t *)(var) = (uint32_t) (buffer)
1255+
# define PHAR_SET_32(destination, source) memcpy(destination, &source, 4)
12541256
#endif
12551257
PHAR_SET_32(sigbuf, phar->sig_flags);
12561258
PHAR_SET_32(sigbuf + 4, signature_length);

0 commit comments

Comments
 (0)