From 8303a9cf380a57d035557a157fe0e4d58e2b3090 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Tue, 14 Dec 2021 16:12:31 +0100 Subject: [PATCH] libelf: Use offsetof to get field of unaligned gcc undefined sanitizer flags: elf_begin.c:230:18: runtime error: member access within misaligned address 0xf796400a for type 'struct Elf64_Shdr', which requires 4 byte alignment struct. We aren't actually accessing the field member of the struct, but are taking the address of it. Which the compiler can take as a hint that the address is correctly aligned. But we can do the same by adding the field offsetof to the base address. Which doesn't trigger a runtime error. Signed-off-by: Mark Wielaard --- libelf/ChangeLog | 5 +++++ libelf/elf_begin.c | 15 +++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 041da9b..96059ef 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,8 @@ +2021-12-15 Mark Wielaard + + * elf_begin.c (get_shnum): Use offsetof to get field of unaligned + struct. + 2021-09-06 Dmitry V. Levin * common.h (allocate_elf): Remove cast of calloc return value. diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c index 93d1e12..bd3399d 100644 --- a/libelf/elf_begin.c +++ b/libelf/elf_begin.c @@ -1,5 +1,6 @@ /* Create descriptor for processing file. Copyright (C) 1998-2010, 2012, 2014, 2015, 2016 Red Hat, Inc. + Copyright (C) 2021 Mark J. Wielaard This file is part of elfutils. Written by Ulrich Drepper , 1998. @@ -170,9 +171,10 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, if (likely (map_address != NULL)) /* gcc will optimize the memcpy to a simple memory access while taking care of alignment issues. */ - memcpy (&size, &((Elf32_Shdr *) ((char *) map_address - + ehdr.e32->e_shoff - + offset))->sh_size, + memcpy (&size, ((char *) map_address + + ehdr.e32->e_shoff + + offset + + offsetof (Elf32_Shdr, sh_size)), sizeof (Elf32_Word)); else if (unlikely ((r = pread_retry (fildes, &size, @@ -227,9 +229,10 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, if (likely (map_address != NULL)) /* gcc will optimize the memcpy to a simple memory access while taking care of alignment issues. */ - memcpy (&size, &((Elf64_Shdr *) ((char *) map_address - + ehdr.e64->e_shoff - + offset))->sh_size, + memcpy (&size, ((char *) map_address + + ehdr.e64->e_shoff + + offset + + offsetof (Elf64_Shdr, sh_size)), sizeof (Elf64_Xword)); else if (unlikely ((r = pread_retry (fildes, &size, -- 2.7.4