Projet

Général

Profil

Télécharger (7,59 ko) Statistiques
| Branche: | Révision:

univnautes-tools / patches / stable / 10 / pbi_rtld-elf.patch @ 4ab3b90b

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

    
(42-42/67)