Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Add forced deletion support to _dl_close_worker
https://sourceware.org/bugzilla/show_bug.cgi?id=17833 I've a shared library that contains both undefined and unique symbols. Then I try to call the following sequence of dlopen: 1. dlopen("./libfoo.so", RTLD_NOW) 2. dlopen("./libfoo.so", RTLD_LAZY | RTLD_GLOBAL) First dlopen call terminates with error because of undefined symbols, but STB_GNU_UNIQUE ones set DF_1_NODELETE flag and hence block library in the memory. The library goes into inconsistent state as several structures remain uninitialized. For instance, relocations for GOT table were not performed. By the time of second dlopen call this library looks like as it would be fully initialized but this is not true: any call through incorrect GOT table leads to segmentation fault. On some systems this inconsistency triggers assertions in the dynamic linker. This patch adds a parameter to _dl_close_worker to implement forced object deletion in case of dlopen() failure: 1. Clears DF_1_NODELETE bit if forced, to allow library to be removed from memory. 2. For each unique symbol that is defined in this object clears appropriate entry in _ns_unique_sym_table. [BZ #17833] * elf/Makefile (tests): Add tst-nodelete. (modules-names): Add tst-nodelete-uniquemod. (tst-nodelete-uniquemod.so-no-z-defs): New. (tst-nodelete-rtldmod.so-no-z-defs): Likewise. (tst-nodelete-zmod.so-no-z-defs): Likewise. ($(objpfx)tst-nodelete): Likewise. ($(objpfx)tst-nodelete.out): Likewise. (LDFLAGS-tst-nodelete): Likewise. (LDFLAGS-tst-nodelete-zmod.so): Likewise. * elf/dl-close.c (_dl_close_worker): Add a parameter to implement forced object deletion. (_dl_close): Pass false to _dl_close_worker. * elf/dl-open.c (_dl_open): Pass true to _dl_close_worker. * elf/tst-nodelete.cc: New file. * elf/tst-nodeletelib.cc: Likewise. * elf/tst-znodeletelib.cc: Likewise. * include/dlfcn.h (_dl_close_worker): Add a new parameter.
- Loading branch information
Pavel Kopyl
authored and
H.J. Lu
committed
Jul 7, 2015
1 parent
890b7a4
commit 02d5e5d
Showing
11 changed files
with
167 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
extern int not_exist (void); | ||
|
||
int foo (void) | ||
{ | ||
return not_exist (); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
extern int not_exist (void); | ||
|
||
inline int make_unique (void) | ||
{ | ||
/* Static variables in inline functions and classes | ||
generate STB_GNU_UNIQUE symbols. */ | ||
static int unique; | ||
return ++unique; | ||
} | ||
|
||
int foo (void) | ||
{ | ||
return make_unique () + not_exist (); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
extern int not_exist (void); | ||
|
||
int foo (void) | ||
{ | ||
return not_exist (); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include "../dlfcn/dlfcn.h" | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
static int | ||
do_test (void) | ||
{ | ||
int result = 0; | ||
|
||
/* This is a test for correct handling of dlopen failures for library that | ||
is loaded with RTLD_NODELETE flag. The first dlopen should fail because | ||
of undefined symbols in shared library. The second dlopen then verifies | ||
that library was properly unloaded. */ | ||
if (dlopen ("tst-nodelete-rtldmod.so", RTLD_NOW | RTLD_NODELETE) != NULL | ||
|| dlopen ("tst-nodelete-rtldmod.so", RTLD_LAZY | RTLD_NOLOAD) != NULL) | ||
{ | ||
printf ("RTLD_NODELETE test failed\n"); | ||
result = 1; | ||
} | ||
|
||
/* This is a test for correct handling of dlopen failures for library that | ||
is linked with '-z nodelete' option and hence has DF_1_NODELETE flag. | ||
The first dlopen should fail because of undefined symbols in shared | ||
library. The second dlopen then verifies that library was properly | ||
unloaded. */ | ||
if (dlopen ("tst-nodelete-zmod.so", RTLD_NOW) != NULL | ||
|| dlopen ("tst-nodelete-zmod.so", RTLD_LAZY | RTLD_NOLOAD) != NULL) | ||
{ | ||
printf ("-z nodelete test failed\n"); | ||
result = 1; | ||
} | ||
|
||
/* This is a test for correct handling of dlopen failures for library | ||
with unique symbols. The first dlopen should fail because of undefined | ||
symbols in shared library. The second dlopen then verifies that library | ||
was properly unloaded. */ | ||
if (dlopen ("tst-nodelete-uniquemod.so", RTLD_NOW) != NULL | ||
|| dlopen ("tst-nodelete-uniquemod.so", RTLD_LAZY | RTLD_NOLOAD) != NULL) | ||
{ | ||
printf ("Unique symbols test failed\n"); | ||
result = 1; | ||
} | ||
|
||
if (result == 0) | ||
printf ("SUCCESS\n"); | ||
|
||
return result; | ||
} | ||
|
||
#define TEST_FUNCTION do_test () | ||
#include "../test-skeleton.c" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
extern int not_exist (void); | ||
|
||
int foo (void) | ||
{ | ||
return not_exist (); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters