1
|
From 956ccdbd6caa186658b95bcea18f41a50a901d73 Mon Sep 17 00:00:00 2001
|
2
|
From: Kris Moore <kris@pcbsd.org>
|
3
|
Date: Mon, 31 Mar 2014 14:54:48 -0400
|
4
|
Subject: [PATCH] Add our custom PBI / rtld fixes, which ensures that rtld will
|
5
|
look for 'rpath' requested libraries in the correct location when we are
|
6
|
running a PBI
|
7
|
|
8
|
---
|
9
|
libexec/rtld-elf/rtld.c | 154 +++++++++++++++++++++++++++++++++++++++++++++---
|
10
|
1 file changed, 145 insertions(+), 9 deletions(-)
|
11
|
|
12
|
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
|
13
|
index 24e56b7..15831cd 100644
|
14
|
--- a/libexec/rtld-elf/rtld.c
|
15
|
+++ b/libexec/rtld-elf/rtld.c
|
16
|
@@ -106,6 +106,7 @@ static void load_filtees(Obj_Entry *, int flags, RtldLockState *);
|
17
|
static void unload_filtees(Obj_Entry *);
|
18
|
static int load_needed_objects(Obj_Entry *, int);
|
19
|
static int load_preload_objects(void);
|
20
|
+static int load_pbipreload_objects(void);
|
21
|
static Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int);
|
22
|
static void map_stacks_exec(RtldLockState *);
|
23
|
static Obj_Entry *obj_from_addr(const void *);
|
24
|
@@ -163,6 +164,16 @@ static bool matched_symbol(SymLook *, const Obj_Entry *, Sym_Match_Result *,
|
25
|
void r_debug_state(struct r_debug *, struct link_map *) __noinline;
|
26
|
|
27
|
/*
|
28
|
+ * For custom rpath PBI support
|
29
|
+ */
|
30
|
+int strpos(const char *haystack, char *needle);
|
31
|
+const char *replace_str(const char *str, char *orig, char *rep);
|
32
|
+int get_modified_path(char *npath, const char *opath);
|
33
|
+char pbidir[MAXPATHLEN];
|
34
|
+int pbiinit = 0;
|
35
|
+static char *usingpbidir;
|
36
|
+
|
37
|
+/*
|
38
|
* Data declarations.
|
39
|
*/
|
40
|
static char *error_message; /* Message for dlerror(), or NULL */
|
41
|
@@ -178,6 +189,8 @@ static char *ld_debug; /* Environment variable for debugging */
|
42
|
static char *ld_library_path; /* Environment variable for search path */
|
43
|
static char *ld_preload; /* Environment variable for libraries to
|
44
|
load first */
|
45
|
+static char *ld_pbipreload; /* Environment variable for PBI runtime wrapper
|
46
|
+ to load first */
|
47
|
static char *ld_elf_hints_path; /* Environment variable for alternative hints path */
|
48
|
static char *ld_tracing; /* Called from ldd to print libs */
|
49
|
static char *ld_utrace; /* Use utrace() to log events. */
|
50
|
@@ -397,7 +410,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
51
|
* future processes to honor the potentially un-safe variables.
|
52
|
*/
|
53
|
if (!trust) {
|
54
|
- if (unsetenv(LD_ "PRELOAD") || unsetenv(LD_ "LIBMAP") ||
|
55
|
+ if (unsetenv(LD_ "PRELOAD") || unsetenv(LD_ "PBIPRELOAD") || unsetenv(LD_ "LIBMAP") ||
|
56
|
unsetenv(LD_ "LIBRARY_PATH") || unsetenv(LD_ "LIBMAP_DISABLE") ||
|
57
|
unsetenv(LD_ "DEBUG") || unsetenv(LD_ "ELF_HINTS_PATH") ||
|
58
|
unsetenv(LD_ "LOADFLTR") || unsetenv(LD_ "LIBRARY_PATH_RPATH")) {
|
59
|
@@ -410,6 +423,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
60
|
libmap_override = getenv(LD_ "LIBMAP");
|
61
|
ld_library_path = getenv(LD_ "LIBRARY_PATH");
|
62
|
ld_preload = getenv(LD_ "PRELOAD");
|
63
|
+ ld_pbipreload = getenv(LD_ "PBIPRELOAD");
|
64
|
+ usingpbidir = getenv("PBI_RUNDIR");
|
65
|
ld_elf_hints_path = getenv(LD_ "ELF_HINTS_PATH");
|
66
|
ld_loadfltr = getenv(LD_ "LOADFLTR") != NULL;
|
67
|
library_path_rpath = getenv(LD_ "LIBRARY_PATH_RPATH");
|
68
|
@@ -422,7 +437,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
69
|
ld_library_path_rpath = false;
|
70
|
}
|
71
|
dangerous_ld_env = libmap_disable || (libmap_override != NULL) ||
|
72
|
- (ld_library_path != NULL) || (ld_preload != NULL) ||
|
73
|
+ (ld_library_path != NULL) || (ld_preload != NULL) || (ld_pbipreload != NULL ) ||
|
74
|
(ld_elf_hints_path != NULL) || ld_loadfltr;
|
75
|
ld_tracing = getenv(LD_ "TRACE_LOADED_OBJECTS");
|
76
|
ld_utrace = getenv(LD_ "UTRACE");
|
77
|
@@ -530,6 +545,9 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
78
|
if (!libmap_disable)
|
79
|
libmap_disable = (bool)lm_init(libmap_override);
|
80
|
|
81
|
+ dbg("loading LD_PBIPRELOAD libraries");
|
82
|
+ if (load_pbipreload_objects() == -1)
|
83
|
+ die();
|
84
|
dbg("loading LD_PRELOAD libraries");
|
85
|
if (load_preload_objects() == -1)
|
86
|
die();
|
87
|
@@ -2012,6 +2030,35 @@ load_preload_objects(void)
|
88
|
return 0;
|
89
|
}
|
90
|
|
91
|
+static int
|
92
|
+load_pbipreload_objects(void)
|
93
|
+{
|
94
|
+ char *p = ld_pbipreload;
|
95
|
+ Obj_Entry *obj;
|
96
|
+ static const char delim[] = " \t:;";
|
97
|
+
|
98
|
+ if (p == NULL)
|
99
|
+ return 0;
|
100
|
+
|
101
|
+ p += strspn(p, delim);
|
102
|
+ while (*p != '\0') {
|
103
|
+ size_t len = strcspn(p, delim);
|
104
|
+ char savech;
|
105
|
+
|
106
|
+ savech = p[len];
|
107
|
+ p[len] = '\0';
|
108
|
+ obj = load_object(p, -1, NULL, 0);
|
109
|
+ if (obj == NULL)
|
110
|
+ return -1; /* XXX - cleanup */
|
111
|
+ obj->z_interpose = true;
|
112
|
+ p[len] = savech;
|
113
|
+ p += len;
|
114
|
+ p += strspn(p, delim);
|
115
|
+ }
|
116
|
+ LD_UTRACE(UTRACE_PRELOAD_FINISHED, NULL, NULL, 0, 0, NULL);
|
117
|
+ return 0;
|
118
|
+}
|
119
|
+
|
120
|
static const char *
|
121
|
printable_path(const char *path)
|
122
|
{
|
123
|
@@ -2684,16 +2731,45 @@ search_library_path(const char *name, const char *path)
|
124
|
if (path == NULL)
|
125
|
return NULL;
|
126
|
|
127
|
- arg.name = name;
|
128
|
- arg.namelen = strlen(name);
|
129
|
- arg.buffer = xmalloc(PATH_MAX);
|
130
|
- arg.buflen = PATH_MAX;
|
131
|
+ /*
|
132
|
+ * When looking for libraries and running as a PBI
|
133
|
+ */
|
134
|
+ if ( usingpbidir != NULL )
|
135
|
+ {
|
136
|
+ char newname[MAXPATHLEN];
|
137
|
+ char newpath[MAXPATHLEN];
|
138
|
+ /* Do the /usr/local -> /usr/pbi mapping */
|
139
|
+ get_modified_path(newname, name);
|
140
|
+ get_modified_path(newpath, path);
|
141
|
+ //printf("search_library_path() name: %s - %s\n", name, newname);
|
142
|
+ //printf("search_library_path() path: %s - %s\n", path, newpath);
|
143
|
+
|
144
|
+ arg.name = newname;
|
145
|
+ arg.namelen = strlen(newname);
|
146
|
+ arg.buffer = xmalloc(PATH_MAX);
|
147
|
+ arg.buflen = PATH_MAX;
|
148
|
+
|
149
|
+ p = path_enumerate(newpath, try_library_path, &arg);
|
150
|
+
|
151
|
+ free(arg.buffer);
|
152
|
+
|
153
|
+ return (p);
|
154
|
+ } else {
|
155
|
+ /*
|
156
|
+ * Traditional library mapping
|
157
|
+ */
|
158
|
+ arg.name = name;
|
159
|
+ arg.namelen = strlen(name);
|
160
|
+ arg.buffer = xmalloc(PATH_MAX);
|
161
|
+ arg.buflen = PATH_MAX;
|
162
|
+
|
163
|
+ p = path_enumerate(path, try_library_path, &arg);
|
164
|
|
165
|
- p = path_enumerate(path, try_library_path, &arg);
|
166
|
+ free(arg.buffer);
|
167
|
|
168
|
- free(arg.buffer);
|
169
|
+ return (p);
|
170
|
+ }
|
171
|
|
172
|
- return (p);
|
173
|
}
|
174
|
|
175
|
int
|
176
|
@@ -4836,3 +4912,63 @@ rtld_strerror(int errnum)
|
177
|
return ("Unknown error");
|
178
|
return (sys_errlist[errnum]);
|
179
|
}
|
180
|
+
|
181
|
+/* PC-BSD custom hacks to rtld / rpath mashing
|
182
|
+ * 03/28/2014
|
183
|
+ * Author: Kris Moore <kris@pcbsd.org>
|
184
|
+ */
|
185
|
+int strpos(const char *haystack, char *needle)
|
186
|
+{
|
187
|
+ char *p = strstr(haystack, needle);
|
188
|
+ if (p) {
|
189
|
+ return p - haystack;
|
190
|
+ }
|
191
|
+ return -1;
|
192
|
+}
|
193
|
+
|
194
|
+const char *replace_str(const char *str, char *orig, char *rep)
|
195
|
+{
|
196
|
+ static char buffer[4096];
|
197
|
+ char *p;
|
198
|
+
|
199
|
+ if(!(p = strstr(str, orig))) // Is 'orig' even in 'str'?
|
200
|
+ return str;
|
201
|
+
|
202
|
+ strncpy(buffer, str, p-str); // Copy characters from 'str' start to 'orig' st$
|
203
|
+ buffer[p-str] = '\0';
|
204
|
+
|
205
|
+ sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig));
|
206
|
+
|
207
|
+ return buffer;
|
208
|
+}
|
209
|
+
|
210
|
+/**********************************************************************************
|
211
|
+* OK, this is where all the path re-mapping happens.
|
212
|
+* We are going to be taking the current filesystem path, and checking it against
|
213
|
+* a list of ones we want to "virtualize" so that it appears we have a different
|
214
|
+* /usr/local namespace
|
215
|
+***********************************************************************************/
|
216
|
+int get_modified_path(char *npath, const char *opath)
|
217
|
+{
|
218
|
+ // Just break out now if path == NULL
|
219
|
+ if ( opath == NULL )
|
220
|
+ return -1;
|
221
|
+
|
222
|
+ // Setup our pbidir variable on first time
|
223
|
+ if ( pbiinit == 0 )
|
224
|
+ {
|
225
|
+ strcpy(pbidir, usingpbidir);
|
226
|
+ strcat(pbidir, "/local");
|
227
|
+ pbiinit=1;
|
228
|
+ }
|
229
|
+
|
230
|
+ // Lastly, lets do all the parsing for /usr/local matching
|
231
|
+ if ( strpos(opath, "/usr/local") == 0 )
|
232
|
+ {
|
233
|
+ strcpy(npath, replace_str(opath, "/usr/local", pbidir));
|
234
|
+ return 0;
|
235
|
+ }
|
236
|
+
|
237
|
+ strcpy(npath, opath);
|
238
|
+ return 0;
|
239
|
+}
|
240
|
--
|
241
|
1.9.1
|
242
|
|