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.

This seems a wrong warning since we aren't accessing the field member
of the struct, but are taking the address of it. 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 <m...@klomp.org>
---
 libelf/ChangeLog   |  5 +++++
 libelf/elf_begin.c | 15 +++++++++------
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 041da9b1..96059eff 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-15  Mark Wielaard  <m...@klomp.org>
+
+       * elf_begin.c (get_shnum): Use offsetof to get field of unaligned
+       struct.
+
 2021-09-06  Dmitry V. Levin  <l...@altlinux.org>
 
        * common.h (allocate_elf): Remove cast of calloc return value.
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 93d1e12f..bd3399de 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 <m...@klomp.org>
    This file is part of elfutils.
    Written by Ulrich Drepper <drep...@redhat.com>, 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.30.2

Reply via email to