/
glibc-2.25-ldso-rpath-prefix-option.diff
176 lines (163 loc) · 5.94 KB
/
glibc-2.25-ldso-rpath-prefix-option.diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
Index: eglibc-2.19/elf/dl-load.c
===================================================================
--- eglibc-2.19.orig/elf/dl-load.c
+++ eglibc-2.19/elf/dl-load.c
@@ -482,7 +482,7 @@ static size_t max_dirnamelen;
static struct r_search_path_elem **
fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
int check_trusted, const char *what, const char *where,
- struct link_map *l)
+ struct link_map *l, const char *rpath_prefix)
{
char *cp;
size_t nelems = 0;
@@ -520,9 +520,23 @@ fillin_rpath (char *rpath, struct r_sear
}
/* See if this directory is already known. */
- for (dirp = GL(dl_all_dirs); dirp != NULL; dirp = dirp->next)
- if (dirp->dirnamelen == len && memcmp (cp, dirp->dirname, len) == 0)
- break;
+ if (__builtin_expect (rpath_prefix != NULL, 0))
+ {
+ /* has rpath_prefix */
+ size_t rpath_prefix_len = strlen (rpath_prefix);
+
+ for (dirp = GL(dl_all_dirs); dirp != NULL; dirp = dirp->next)
+ if (dirp->dirnamelen == (rpath_prefix_len+len) &&
+ (memcmp (cp, rpath_prefix, rpath_prefix_len) == 0) &&
+ (memcmp (cp+rpath_prefix_len, dirp->dirname, len) == 0))
+ break;
+ }
+ else
+ {
+ for (dirp = GL(dl_all_dirs); dirp != NULL; dirp = dirp->next)
+ if (dirp->dirnamelen == len && memcmp (cp, dirp->dirname, len) == 0)
+ break;
+ }
if (dirp != NULL)
{
@@ -540,22 +554,43 @@ fillin_rpath (char *rpath, struct r_sear
size_t cnt;
enum r_dir_status init_val;
size_t where_len = where ? strlen (where) + 1 : 0;
+ size_t rpath_prefix_len = 0;
+
+ if (__builtin_expect (rpath_prefix != NULL, 0)
+ && !__libc_enable_secure)
+ {
+ rpath_prefix_len = strlen (rpath_prefix);
+ if (*cp != '/') rpath_prefix_len++; /* need to add a '/' */
+ }
/* It's a new directory. Create an entry and add it. */
dirp = (struct r_search_path_elem *)
malloc (sizeof (*dirp) + ncapstr * sizeof (enum r_dir_status)
- + where_len + len + 1);
+ + where_len + rpath_prefix_len + len + 1);
if (dirp == NULL)
_dl_signal_error (ENOMEM, NULL, NULL,
N_("cannot create cache for search path"));
dirp->dirname = ((char *) dirp + sizeof (*dirp)
+ ncapstr * sizeof (enum r_dir_status));
- *((char *) __mempcpy ((char *) dirp->dirname, cp, len)) = '\0';
- dirp->dirnamelen = len;
+ if (rpath_prefix_len == 0)
+ {
+ *((char *) __mempcpy ((char *) dirp->dirname, cp, len)) = '\0';
+ }
+ else
+ {
+ char *prefixend;
+
+ prefixend = (char *) __mempcpy ((char *) dirp->dirname,
+ rpath_prefix, rpath_prefix_len);
+ if (*cp != '/')
+ prefixend[-1] = '/'; /* replace \0 */
+ *((char *) __mempcpy (prefixend, cp, len)) = '\0';
+ }
+ dirp->dirnamelen = len + rpath_prefix_len;
- if (len > max_dirnamelen)
- max_dirnamelen = len;
+ if ((len + rpath_prefix_len) > max_dirnamelen)
+ max_dirnamelen = len + rpath_prefix_len;
/* We have to make sure all the relative directories are
never ignored. The current directory might change and
@@ -566,7 +601,8 @@ fillin_rpath (char *rpath, struct r_sear
dirp->what = what;
if (__glibc_likely (where != NULL))
- dirp->where = memcpy ((char *) dirp + sizeof (*dirp) + len + 1
+ dirp->where = memcpy ((char *) dirp + sizeof (*dirp)
+ + rpath_prefix_len + len + 1
+ (ncapstr * sizeof (enum r_dir_status)),
where, where_len);
else
@@ -668,7 +704,7 @@ decompose_rpath (struct r_search_path_st
_dl_signal_error (ENOMEM, NULL, NULL, errstring);
}
- fillin_rpath (copy, result, ":", 0, what, where, l);
+ fillin_rpath (copy, result, ":", 0, what, where, l, GLRO(dl_rpath_prefix));
/* Free the copied RPATH string. `fillin_rpath' make own copies if
necessary. */
@@ -871,7 +907,7 @@ _dl_init_paths (const char *llp)
(void) fillin_rpath (llp_tmp, env_path_list.dirs, ":;",
__libc_enable_secure, "LD_LIBRARY_PATH",
- NULL, l);
+ NULL, l, NULL/*no prefix*/);
if (env_path_list.dirs[0] == NULL)
{
Index: eglibc-2.19/elf/dl-support.c
===================================================================
--- eglibc-2.19.orig/elf/dl-support.c
+++ eglibc-2.19/elf/dl-support.c
@@ -61,6 +61,9 @@ const char *_dl_profile_output;
ignored. */
const char *_dl_inhibit_rpath;
+/* prefix to be added to all RUNPATHs and RPATHs */
+const char *_dl_rpath_prefix = NULL;
+
/* The map for the object we will profile. */
struct link_map *_dl_profile_map;
Index: eglibc-2.19/elf/rtld.c
===================================================================
--- eglibc-2.19.orig/elf/rtld.c
+++ eglibc-2.19/elf/rtld.c
@@ -991,6 +991,15 @@ dl_main (const ElfW(Phdr) *phdr,
_dl_argc -= 2;
_dl_argv += 2;
}
+ else if (! strcmp (_dl_argv[1], "--rpath-prefix")
+ && _dl_argc > 2)
+ {
+ GLRO(dl_rpath_prefix) = _dl_argv[2];
+
+ _dl_skip_args += 2;
+ _dl_argc -= 2;
+ _dl_argv += 2;
+ }
else if (! strcmp (_dl_argv[1], "--audit") && _dl_argc > 2)
{
process_dl_audit (_dl_argv[2]);
@@ -1025,6 +1034,7 @@ of this helper program; chances are you
--inhibit-cache Do not use " LD_SO_CACHE "\n\
--library-path PATH use given PATH instead of content of the environment\n\
variable LD_LIBRARY_PATH\n\
+ --rpath-prefix PREFIX add PREFIX to every RUNPATH and RPATH component\n\
--inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\
in LIST\n\
--audit LIST use objects named in LIST as auditors\n");
Index: eglibc-2.19/sysdeps/generic/ldsodefs.h
===================================================================
--- eglibc-2.19.orig/sysdeps/generic/ldsodefs.h
+++ eglibc-2.19/sysdeps/generic/ldsodefs.h
@@ -600,6 +600,12 @@ struct rtld_global_ro
/* List of auditing interfaces. */
struct audit_ifaces *_dl_audit;
unsigned int _dl_naudit;
+#endif
+
+ /* prefix for RPATH + RUNPATH components. */
+ EXTERN const char *_dl_rpath_prefix;
+
+#ifdef SHARED
};
# define __rtld_global_attribute__
# ifdef IS_IN_rtld