summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2014-04-22 00:14:03 +0000
committerRobert Mustacchi <rm@joyent.com>2015-02-09 15:34:39 -0800
commit4812581794004eff0af2b765b832403b30bf64ab (patch)
treefbd18690340f7e88c6aa05dde1f1466ccfcf0861 /usr/src/cmd
parent1f2ca518aeecee8616fccc0c46a339773faea7d5 (diff)
downloadillumos-gate-4812581794004eff0af2b765b832403b30bf64ab.tar.gz
4996 rtld _init race leads to incorrect symbol values
Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Dan McDonald <danmcd@omniti.com> Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/sgs/include/debug.h3
-rw-r--r--usr/src/cmd/sgs/include/rtld.h3
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/liblddbg.msg2
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/llib-llddbg2
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/mapfile-vers2
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/util.c13
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README1
-rw-r--r--usr/src/cmd/sgs/rtld/common/_rtld.h1
-rw-r--r--usr/src/cmd/sgs/rtld/common/util.c23
9 files changed, 21 insertions, 29 deletions
diff --git a/usr/src/cmd/sgs/include/debug.h b/usr/src/cmd/sgs/include/debug.h
index 9db202574d..5f740afe57 100644
--- a/usr/src/cmd/sgs/include/debug.h
+++ b/usr/src/cmd/sgs/include/debug.h
@@ -502,7 +502,6 @@ extern void Dbg_help(void);
#define Dbg_util_intoolate Dbg64_util_intoolate
#define Dbg_util_lcinterface Dbg64_util_lcinterface
#define Dbg_util_nl Dbg64_util_nl
-#define Dbg_util_no_init Dbg64_util_no_init
#define Dbg_util_scc_entry Dbg64_util_scc_entry
#define Dbg_util_scc_title Dbg64_util_scc_title
#define Dbg_util_str Dbg64_util_str
@@ -736,7 +735,6 @@ extern void Dbg_help(void);
#define Dbg_util_intoolate Dbg32_util_intoolate
#define Dbg_util_lcinterface Dbg32_util_lcinterface
#define Dbg_util_nl Dbg32_util_nl
-#define Dbg_util_no_init Dbg32_util_no_init
#define Dbg_util_scc_entry Dbg32_util_scc_entry
#define Dbg_util_scc_title Dbg32_util_scc_title
#define Dbg_util_str Dbg32_util_str
@@ -1051,7 +1049,6 @@ extern void Dbg_util_edge_out(Rt_map *, Rt_map *);
extern void Dbg_util_intoolate(Rt_map *);
extern void Dbg_util_lcinterface(Rt_map *, int, char *);
extern void Dbg_util_nl(Lm_list *, int);
-extern void Dbg_util_no_init(Rt_map *);
extern void Dbg_util_scc_entry(Rt_map *, uint_t);
extern void Dbg_util_scc_title(Lm_list *, int);
extern void Dbg_util_str(Lm_list *, const char *);
diff --git a/usr/src/cmd/sgs/include/rtld.h b/usr/src/cmd/sgs/include/rtld.h
index 344671d515..65eb25c4b1 100644
--- a/usr/src/cmd/sgs/include/rtld.h
+++ b/usr/src/cmd/sgs/include/rtld.h
@@ -719,7 +719,10 @@ struct rt_map {
Capchain *rt_capchain; /* capabilities chain data */
uint_t rt_cntl; /* link-map control list we belong to */
uint_t rt_aflags; /* auditor flags, see LML_TFLG_AUD_ */
+ Rt_cond rt_cv; /* for waiting on flags changes */
+ Rt_lock rt_lock; /* for coordinating flags changes */
/* address of _init */
+ thread_t rt_init_thread; /* thread id in this lm's _init */
void (*rt_init)(void);
/* address of _fini */
void (*rt_fini)(void);
diff --git a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
index 71f432220f..34c012acab 100644
--- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
+++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
@@ -1102,8 +1102,6 @@
@ MSG_UTL_DYN "dynamically triggered"
@ MSG_UTL_DONE "done"
-@ MSG_UTL_NOINIT "warning: calling %s whose init has not completed"
-
@ MSG_UTL_DBNOTIFY "notify debugger: event: %s state: %s"
@ MSG_UTL_SCC_TITLE " cycle detected - sorting cyclic dependencies in %s"
diff --git a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
index 0b6bfc747b..e3a43c6e0c 100644
--- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
+++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
@@ -502,8 +502,6 @@ void Dbg32_util_lcinterface(Rt_map *, int, char *);
void Dbg64_util_lcinterface(Rt_map *, int, char *);
void Dbg32_util_nl(Lm_list *, int);
void Dbg64_util_nl(Lm_list *, int);
-void Dbg32_util_no_init(Rt_map *);
-void Dbg64_util_no_init(Rt_map *);
void Dbg32_util_scc_entry(Rt_map *, uint_t);
void Dbg64_util_scc_entry(Rt_map *, uint_t);
void Dbg32_util_scc_title(Lm_list *, int);
diff --git a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
index 0e4338fce1..1fac50603d 100644
--- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
+++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
@@ -490,8 +490,6 @@ SYMBOL_VERSION SUNWprivate_4.83 {
Dbg64_util_intoolate;
Dbg32_util_nl;
Dbg64_util_nl;
- Dbg32_util_no_init;
- Dbg64_util_no_init;
Dbg32_util_scc_entry;
Dbg64_util_scc_entry;
Dbg32_util_scc_title;
diff --git a/usr/src/cmd/sgs/liblddbg/common/util.c b/usr/src/cmd/sgs/liblddbg/common/util.c
index 02de483a82..575a9bd15f 100644
--- a/usr/src/cmd/sgs/liblddbg/common/util.c
+++ b/usr/src/cmd/sgs/liblddbg/common/util.c
@@ -66,19 +66,6 @@ Dbg_util_call_init(Rt_map *lmp, int flag)
}
void
-Dbg_util_no_init(Rt_map *lmp)
-{
- Lm_list *lml = LIST(lmp);
-
- if (DBG_NOTCLASS(DBG_C_INIT))
- return;
-
- Dbg_util_nl(lml, DBG_NL_STD);
- dbg_print(lml, MSG_INTL(MSG_UTL_NOINIT), NAME(lmp));
- Dbg_util_nl(lml, DBG_NL_STD);
-}
-
-void
Dbg_util_intoolate(Rt_map *lmp)
{
Lm_list *lml = LIST(lmp);
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README
index 6688c34255..f303ba6053 100644
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README
@@ -1654,3 +1654,4 @@ Bugid Risk Synopsis
4270 ld(1) argument error reporting is still pretty bad
4383 libelf can't write extended sections when ELF_F_LAYOUT
4959 completely discarded merged string sections will corrupt output objects
+4996 rtld _init race leads to incorrect symbol values
diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h
index 3cbb58fe25..ece14a855e 100644
--- a/usr/src/cmd/sgs/rtld/common/_rtld.h
+++ b/usr/src/cmd/sgs/rtld/common/_rtld.h
@@ -764,7 +764,6 @@ extern int remove_hdl(Grp_hdl *, Rt_map *, int *);
extern void remove_lmc(Lm_list *, Rt_map *, Aliste, const char *);
extern void remove_lml(Lm_list *);
extern void remove_so(Lm_list *, Rt_map *, Rt_map *);
-extern int rt_cond_wait(Rt_cond *, Rt_lock *);
extern int rt_critical(void);
extern int rt_bind_guard(int);
extern int rt_bind_clear(int);
diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c
index 5f9979ddf0..a702b20e78 100644
--- a/usr/src/cmd/sgs/rtld/common/util.c
+++ b/usr/src/cmd/sgs/rtld/common/util.c
@@ -627,16 +627,22 @@ is_dep_init(Rt_map *dlmp, Rt_map *clmp)
if ((dlmp == clmp) || (rtld_flags & RT_FL_INITFIRST))
return;
+ (void) rt_mutex_lock(&dlmp->rt_lock);
+ while (dlmp->rt_init_thread != rt_thr_self() && (FLAGS(dlmp) &
+ (FLG_RT_RELOCED | FLG_RT_INITCALL | FLG_RT_INITDONE)) ==
+ (FLG_RT_RELOCED | FLG_RT_INITCALL)) {
+ leave(LIST(dlmp), 0);
+ (void) _lwp_cond_wait(&dlmp->rt_cv, (mutex_t *)&dlmp->rt_lock);
+ (void) rt_mutex_unlock(&dlmp->rt_lock);
+ (void) enter(0);
+ (void) rt_mutex_lock(&dlmp->rt_lock);
+ }
+ (void) rt_mutex_unlock(&dlmp->rt_lock);
+
if ((FLAGS(dlmp) & (FLG_RT_RELOCED | FLG_RT_INITDONE)) ==
(FLG_RT_RELOCED | FLG_RT_INITDONE))
return;
- if ((FLAGS(dlmp) & (FLG_RT_RELOCED | FLG_RT_INITCALL)) ==
- (FLG_RT_RELOCED | FLG_RT_INITCALL)) {
- DBG_CALL(Dbg_util_no_init(dlmp));
- return;
- }
-
if ((tobj = calloc(2, sizeof (Rt_map *))) != NULL) {
tobj[0] = dlmp;
call_init(tobj, DBG_INIT_DYN);
@@ -717,6 +723,7 @@ call_init(Rt_map **tobj, int flag)
continue;
FLAGS(lmp) |= FLG_RT_INITCALL;
+ lmp->rt_init_thread = rt_thr_self();
/*
* Establish an initfirst state if necessary - no other inits
@@ -752,7 +759,11 @@ call_init(Rt_map **tobj, int flag)
* signifies that a .fini must be called should it exist.
* Clear the sort field for use in later .fini processing.
*/
+ (void) rt_mutex_lock(&lmp->rt_lock);
FLAGS(lmp) |= FLG_RT_INITDONE;
+ lmp->rt_init_thread = (thread_t)0;
+ (void) _lwp_cond_broadcast(&lmp->rt_cv);
+ (void) rt_mutex_unlock(&lmp->rt_lock);
SORTVAL(lmp) = -1;
/*