public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
From: Mark Wielaard <mark@klomp.org>
To: elfutils-devel@sourceware.org
Cc: hsm2@rice.edu, Mark Wielaard <mark@klomp.org>
Subject: [PATCH 06/16] libelf: Make elf32_getchdr and elf64_getchdr thread-safe
Date: Tue, 10 Oct 2023 15:42:50 +0200	[thread overview]
Message-ID: <20231010134300.53830-6-mark@klomp.org> (raw)
In-Reply-To: <20231010134300.53830-1-mark@klomp.org>

From: Heather McIntyre <hsm2@rice.edu>

	* libelf/elf32_getchdr.c: Move getchdr function to
	elf32_getchdr.h.
	* libelf/elf32_getchdr.h: New file.
	Add macro to create getchdr_wrlock.
	* libelf/elf32_updatenull.c: Change call from getchdr to
	getchdr_wrlock.
	* libelf/elf_getdata.c: Add elf_getdata_wrlock.
	* libelf/libelfP.h: Add internal function declarations.

Signed-off-by: Heather S. McIntyre <hsm2@rice.edu>
Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libelf/elf32_getchdr.c    | 46 +++--------------------------
 libelf/elf32_getchdr.h    | 61 +++++++++++++++++++++++++++++++++++++++
 libelf/elf32_updatenull.c |  2 +-
 libelf/elf_getdata.c      | 14 +++++++++
 libelf/libelfP.h          |  4 +++
 5 files changed, 84 insertions(+), 43 deletions(-)
 create mode 100644 libelf/elf32_getchdr.h

diff --git a/libelf/elf32_getchdr.c b/libelf/elf32_getchdr.c
index 982a614c..41591300 100644
--- a/libelf/elf32_getchdr.c
+++ b/libelf/elf32_getchdr.c
@@ -38,46 +38,8 @@
 # define LIBELFBITS 32
 #endif
 
+#define ELF_WRLOCK_HELD 1
+#include "elf32_getchdr.h"
 
-ElfW2(LIBELFBITS,Chdr) *
-elfw2(LIBELFBITS,getchdr) (Elf_Scn *scn)
-{
-  ElfW2(LIBELFBITS,Shdr) *shdr = elfw2(LIBELFBITS,getshdr) (scn);
-  if (shdr == NULL)
-    return NULL;
-
-  /* Must have SHF_COMPRESSED flag set.  Allocated or no bits sections
-     can never be compressed.  */
-  if ((shdr->sh_flags & SHF_ALLOC) != 0)
-    {
-      __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS);
-      return NULL;
-    }
-
-  if (shdr->sh_type == SHT_NULL
-      || shdr->sh_type == SHT_NOBITS)
-    {
-      __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE);
-      return NULL;
-    }
-
-  if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
-    {
-      __libelf_seterrno (ELF_E_NOT_COMPRESSED);
-      return NULL;
-    }
-
-  /* This makes sure the data is in the correct format, so we don't
-     need to swap fields. */
-  Elf_Data *d  = elf_getdata (scn, NULL);
-  if (d == NULL)
-    return NULL;
-
-  if (d->d_size < sizeof (ElfW2(LIBELFBITS,Chdr)) || d->d_buf == NULL)
-    {
-      __libelf_seterrno (ELF_E_INVALID_DATA);
-      return NULL;
-    }
-
-  return (ElfW2(LIBELFBITS,Chdr) *) d->d_buf;
-}
+#define ELF_WRLOCK_HELD 0
+#include "elf32_getchdr.h"
\ No newline at end of file
diff --git a/libelf/elf32_getchdr.h b/libelf/elf32_getchdr.h
new file mode 100644
index 00000000..04d47e7a
--- /dev/null
+++ b/libelf/elf32_getchdr.h
@@ -0,0 +1,61 @@
+#undef ADD_ROUTINE_PREFIX
+#undef ADD_ROUTINE_SUFFIX
+
+#if ELF_WRLOCK_HELD
+#define CONCAT(x,y) x##y
+#define ADD_ROUTINE_PREFIX(y) CONCAT(__,y)
+#define ADD_ROUTINE_SUFFIX(x) x ## _wrlock
+#define INTERNAL internal_function
+#else
+#define ADD_ROUTINE_PREFIX(y) y
+#define ADD_ROUTINE_SUFFIX(x) x
+#define INTERNAL
+#endif
+
+ElfW2(LIBELFBITS,Chdr) *
+INTERNAL
+ADD_ROUTINE_PREFIX(elfw2(LIBELFBITS, ADD_ROUTINE_SUFFIX(getchdr))) (Elf_Scn *scn)
+{
+
+  ElfW2(LIBELFBITS,Shdr) *shdr = ADD_ROUTINE_PREFIX(elfw2(LIBELFBITS, ADD_ROUTINE_SUFFIX(getshdr)))(scn);
+
+  if (shdr == NULL)
+    return NULL;
+
+  /* Must have SHF_COMPRESSED flag set.  Allocated or no bits sections
+     can never be compressed.  */
+  if ((shdr->sh_flags & SHF_ALLOC) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS);
+      return NULL;
+    }
+
+  if (shdr->sh_type == SHT_NULL
+      || shdr->sh_type == SHT_NOBITS)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE);
+      return NULL;
+    }
+
+  if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+    {
+      __libelf_seterrno (ELF_E_NOT_COMPRESSED);
+      return NULL;
+    }
+
+  /* This makes sure the data is in the correct format, so we don't
+     need to swap fields. */
+  Elf_Data *d  = ADD_ROUTINE_PREFIX(ADD_ROUTINE_SUFFIX(elf_getdata)) (scn, NULL);
+  if (d == NULL)
+    return NULL;
+
+  if (d->d_size < sizeof (ElfW2(LIBELFBITS,Chdr)) || d->d_buf == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_DATA);
+      return NULL;
+    }
+
+  return (ElfW2(LIBELFBITS,Chdr) *) d->d_buf;
+}
+#undef INTERNAL
+#undef ELF_WRLOCK_HELD
\ No newline at end of file
diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index c5d26b00..3594e8ba 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -407,7 +407,7 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
 		  else
 		    {
 		      ElfW2(LIBELFBITS,Chdr) *chdr;
-		      chdr = elfw2(LIBELFBITS,getchdr) (scn);
+		      chdr = __elfw2(LIBELFBITS,getchdr_wrlock) (scn);
 		      if (unlikely (chdr == NULL))
 			return -1;
 		      sh_size = chdr->ch_size;
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 5ebd270f..7c3ac043 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -582,4 +582,18 @@ elf_getdata (Elf_Scn *scn, Elf_Data *data)
 
   return result;
 }
+
+Elf_Data *
+internal_function
+__elf_getdata_wrlock (Elf_Scn *scn, Elf_Data *data)
+{
+  Elf_Data *result;
+
+  if (scn == NULL)
+    return NULL;
+
+  result = __elf_getdata_rdlock (scn, data);
+
+  return result;
+}
 INTDEF(elf_getdata)
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 96476064..ed061abb 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -514,6 +514,8 @@ extern Elf32_Shdr *__elf32_getshdr_rdlock (Elf_Scn *__scn) internal_function;
 extern Elf64_Shdr *__elf64_getshdr_rdlock (Elf_Scn *__scn) internal_function;
 extern Elf32_Shdr *__elf32_getshdr_wrlock (Elf_Scn *__scn) internal_function;
 extern Elf64_Shdr *__elf64_getshdr_wrlock (Elf_Scn *__scn) internal_function;
+extern Elf32_Chdr *__elf32_getchdr_wrlock (Elf_Scn *__scn) internal_function;
+extern Elf64_Chdr *__elf64_getchdr_wrlock (Elf_Scn *__scn) internal_function;
 extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index)
      attribute_hidden;
 extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn)
@@ -523,6 +525,8 @@ extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data)
      attribute_hidden;
 extern Elf_Data *__elf_getdata_rdlock (Elf_Scn *__scn, Elf_Data *__data)
      internal_function;
+extern Elf_Data *__elf_getdata_wrlock (Elf_Scn *__scn, Elf_Data *__data)
+     internal_function;
 extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data)
      attribute_hidden;
 /* Should be called to setup first section data element if
-- 
2.41.0


  parent reply	other threads:[~2023-10-10 13:43 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-08 17:07 [PATCH] Fix thread-safety for elfutils Heather McIntyre
2023-08-21 22:08 ` John Mellor-Crummey
2023-08-25 14:10   ` Mark Wielaard
2023-10-10 13:40 ` Mark Wielaard
2023-10-10 13:42   ` [PATCH 01/16] lib: Add new once_define and once macros to eu-config.h Mark Wielaard
2023-10-10 13:42     ` [PATCH 02/16] libelf: Make elf_version thread-safe Mark Wielaard
2023-10-10 14:00       ` Mark Wielaard
2023-10-17 19:05         ` Heather McIntyre
2023-10-19 21:00           ` Mark Wielaard
2023-10-10 13:42     ` [PATCH 03/16] libelf: Fix deadlock in __libelf_readall Mark Wielaard
2023-10-10 15:06       ` Mark Wielaard
2023-10-17 19:11         ` Heather McIntyre
2023-11-09 13:26           ` Mark Wielaard
2023-10-10 13:42     ` [PATCH 04/16] libelf: Fix deadlock in elf_cntl Mark Wielaard
2023-10-10 15:23       ` Mark Wielaard
2023-10-17 19:14         ` Heather McIntyre
2023-10-10 13:42     ` [PATCH 05/16] libelf: Fix elf_end deadlock Mark Wielaard
2023-10-10 15:28       ` Mark Wielaard
2023-10-10 13:42     ` Mark Wielaard [this message]
2023-10-10 16:28       ` [PATCH 06/16] libelf: Make elf32_getchdr and elf64_getchdr thread-safe Mark Wielaard
2023-10-10 13:42     ` [PATCH 07/16] lib: Add eu_tsearch and eu_tfind Mark Wielaard
2023-10-10 16:51       ` Mark Wielaard
2023-10-17 20:52         ` Heather McIntyre
2023-10-10 13:42     ` [PATCH 08/16] libcpu: Change calls for tsearch/tfind to eu_tsearch/eu_tfind Mark Wielaard
2023-10-10 21:10       ` Mark Wielaard
2023-10-10 13:42     ` [PATCH 09/16] src: Use eu-search in nm and findtextrel Mark Wielaard
2023-10-10 21:25       ` Mark Wielaard
2023-10-17 19:20         ` Heather McIntyre
2023-10-10 13:42     ` [PATCH 10/16] libdw: make dwarf_getalt thread-safe Mark Wielaard
2023-10-10 22:02       ` Mark Wielaard
2023-10-17 19:25         ` Heather McIntyre
2023-10-10 13:42     ` [PATCH 11/16] libdw: Add locking around __libdw_dieabbrev for dwarf_hasattr Mark Wielaard
2023-10-11 15:10       ` Mark Wielaard
2023-10-17 19:57       ` Heather McIntyre
2023-10-19 22:06         ` Mark Wielaard
2023-10-10 13:42     ` [PATCH 12/16] libdw: Make libdw_find_split_unit thread-safe Mark Wielaard
2023-10-11 17:17       ` Mark Wielaard
2023-10-17 20:01         ` Heather McIntyre
2023-10-10 13:42     ` [PATCH 13/16] libdw: Make libdw_findcu thread-safe Mark Wielaard
2023-10-12 22:02       ` Mark Wielaard
2023-10-17 20:10         ` Heather McIntyre
2023-10-10 13:42     ` [PATCH 14/16] libdw,libdwfl: Use eu-search for thread-safety Mark Wielaard
2023-10-12 22:05       ` Mark Wielaard
2023-10-10 13:42     ` [PATCH 15/16] tests: Add eu-search tests Mark Wielaard
2023-10-13 14:38       ` Mark Wielaard
2023-10-10 13:43     ` [PATCH 16/16] configure: No longer mark --enable-thread-safety as EXPERIMENTAL Mark Wielaard
2023-10-12 22:09       ` Mark Wielaard
2023-10-10 13:54     ` [PATCH 01/16] lib: Add new once_define and once macros to eu-config.h Mark Wielaard
2023-10-14 15:39   ` [PATCH] Fix thread-safety for elfutils Mark Wielaard
2023-10-14 18:29     ` Heather McIntyre
2023-10-17 15:04       ` Mark Wielaard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231010134300.53830-6-mark@klomp.org \
    --to=mark@klomp.org \
    --cc=elfutils-devel@sourceware.org \
    --cc=hsm2@rice.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).