[PATCH] libelf: Use offsetof to get field of unaligned

Mark Wielaard mark@klomp.org
Wed Dec 15 22:05:44 GMT 2021


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 <mark@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  <mark@klomp.org>
+
+	* elf_begin.c (get_shnum): Use offsetof to get field of unaligned
+	struct.
+
 2021-09-06  Dmitry V. Levin  <ldv@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 <mark@klomp.org>
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@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



More information about the Elfutils-devel mailing list