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 <[email protected]>
---
 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  <[email protected]>
+
+       * elf_begin.c (get_shnum): Use offsetof to get field of unaligned
+       struct.
+
 2021-09-06  Dmitry V. Levin  <[email protected]>
 
        * 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 <[email protected]>
    This file is part of elfutils.
    Written by Ulrich Drepper <[email protected]>, 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