From 5ea4640cc9dd96b561214c35092cc1024c8a72f8 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 26 Jun 2024 23:01:47 +0200 Subject: [PATCH] cli_check_mydoom_log: Avoid unaligned access. fmap_need_off_once() may return an unaligned pointer. This in return leads to an unaligned access during the load of the uint32_t variables loading to failures on architectures not supporting unaligned access. This was reported to the Debian BTS as #1073128. [bigeasy: Commit message, reworked the patch a bit]. Link: https://bugs.debian.org/1073128 Signed-off-by: Sebastian Andrzej Siewior --- libclamav/special.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/libclamav/special.c b/libclamav/special.c index 506e5799da..4544e59eeb 100644 --- a/libclamav/special.c +++ b/libclamav/special.c @@ -48,7 +48,8 @@ int cli_check_mydoom_log(cli_ctx *ctx) { - const uint32_t *record; + uint32_t record[16]; + const uint32_t *ptr; uint32_t check, key; fmap_t *map = ctx->fmap; unsigned int blocks = map->len / (8 * 4); @@ -59,14 +60,24 @@ int cli_check_mydoom_log(cli_ctx *ctx) if (blocks > 5) blocks = 5; - record = fmap_need_off_once(map, 0, 8 * 4 * blocks); - if (!record) + /* + * The following pointer might not be properly aligned. There there is + * memcmp() + memcpy() workaround to avoid performing an unaligned access + * while reading the uint32_t. + */ + ptr = fmap_need_off_once(map, 0, 8 * 4 * blocks); + if (!ptr) return CL_CLEAN; + while (blocks) { /* This wasn't probably intended but that's what the current code does anyway */ - if (record[--blocks] == 0xffffffff) + const uint32_t marker_ff = 0xffffffff; + + if (!memcmp(&ptr[--blocks], &marker_ff, sizeof(uint32_t))) return CL_CLEAN; } + memcpy(record, ptr, sizeof(record)); + key = ~be32_to_host(record[0]); check = (be32_to_host(record[1]) ^ key) + (be32_to_host(record[2]) ^ key) +