This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH v4] dl-load: add memory barrier before updating the next
- From: Maninder Singh <maninder1 dot s at samsung dot com>
- To: libc-alpha at sourceware dot org, triegel at redhat dot com, szabolcs dot nagy at arm dot com
- Cc: pankaj dot m at samsung dot com, ajeet dot y at samsung dot com, a dot sahrawat at samsung dot com, lalit dot mohan at samsung dot com, akhilesh dot k at samsung dot com, hakbong5 dot lee at samsung dot com, Maninder Singh <maninder1 dot s at samsung dot com>, Vaneet Narang <v dot narang at samsung dot com>
- Date: Mon, 10 Apr 2017 13:50:46 +0530
- Subject: [PATCH v4] dl-load: add memory barrier before updating the next
- Authentication-results: sourceware.org; auth=none
- Cms-type: 105P
- Dlp-filter: Pass
- References: <CGME20170410082212epcas5p4cb83ce1c13504510c6458ccd0eb81c8d@epcas5p4.samsung.com>
[BZ #21349]: race condition between dl_open and rtld lazy symbol resolve.
Issue Fix: race condition between add_name_to_object & _dl_name_match_p.
One threads calling dlopen which further calls add_name_to_object &
other thread trying to resolve RTLD_LAZY symbols through
_dl_runtime_resolve which further calls.
_dl_name_match_p checks if libname->next is valid, then it assumes
libname->next->name to be valid. Also add_name_to_object initialized
name first and then sets valid next pointer.
This patch avoids any reorder of instruction when next is set before
name to avoid any race.
so as suggested by Torvald Riegel <triegel@redhat.com>:
"Add C11 memory barrier before updating the liblist next and add comments
for barriers."
Signed-off-by: Vaneet Narang <v.narang@samsung.com>
Signed-off-by: Maninder Singh <maninder1.s@samsung.com>
---
v1 -> v2: use C11 atomics rather than direct memory barriers.
v2 -> v3: use comments for barriers and enter Bugzilla ID.
v3 -> v4: remove extra parens.
elf/dl-load.c | 5 ++++-
elf/dl-misc.c | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/elf/dl-load.c b/elf/dl-load.c
index a5318f9..03c6afb 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -418,7 +418,10 @@ add_name_to_object (struct link_map *l, const char *name)
newname->name = memcpy (newname + 1, name, name_len);
newname->next = NULL;
newname->dont_free = 0;
- lastp->next = newname;
+ /* We need release memory order here because we need to synchronize
+ with other thread doing _dl_runtime_resolve which calls _dl_name_match_p
+ to traverse all names added to libname_list */
+ atomic_store_release (&lastp->next, newname);
}
/* Standard search directories. */
diff --git a/elf/dl-misc.c b/elf/dl-misc.c
index 1e9a6ee..a26d6f6 100644
--- a/elf/dl-misc.c
+++ b/elf/dl-misc.c
@@ -295,7 +295,10 @@ _dl_name_match_p (const char *name, const struct link_map *map)
if (strcmp (name, runp->name) == 0)
return 1;
else
- runp = runp->next;
+ /* We need to acquire memory order here because we need to synchronize
+ with other thread calling dlopen and adding new name to libname_list
+ through add_name_to_object */
+ runp = atomic_load_acquire (&runp->next);
return 0;
}
--
1.7.1