]>
Commit | Line | Data |
---|---|---|
12788f63 MT |
1 | 2011-03-14 Andreas Schwab <schwab@redhat.com> |
2 | ||
3 | * elf/dl-load.c (is_dst): Remove parameter secure, all callers | |
4 | changed. Don't check for isolated use. | |
5 | (_dl_dst_substitute): Ignore rpath elements containing | |
6 | non-isolated use of $ORIGIN when privileged. | |
7 | ||
8 | * elf/dl-load.c (_dl_dst_substitute): When skipping the first | |
9 | rpath element also skip the following colon. | |
10 | (expand_dynamic_string_token): Add is_path parameter and pass | |
11 | down to DL_DST_REQUIRED and _dl_dst_substitute. | |
12 | (decompose_rpath): Call expand_dynamic_string_token with | |
13 | non-zero is_path. Ignore empty rpaths. | |
14 | (_dl_map_object_from_fd): Call expand_dynamic_string_token | |
15 | with zero is_path. | |
16 | ||
17 | Index: glibc-2.12-2-gc4ccff1/elf/dl-load.c | |
18 | =================================================================== | |
19 | --- glibc-2.12-2-gc4ccff1.orig/elf/dl-load.c | |
20 | +++ glibc-2.12-2-gc4ccff1/elf/dl-load.c | |
21 | @@ -169,8 +169,7 @@ local_strdup (const char *s) | |
22 | ||
23 | ||
24 | static size_t | |
25 | -is_dst (const char *start, const char *name, const char *str, | |
26 | - int is_path, int secure) | |
27 | +is_dst (const char *start, const char *name, const char *str, int is_path) | |
28 | { | |
29 | size_t len; | |
30 | bool is_curly = false; | |
31 | @@ -199,11 +198,6 @@ is_dst (const char *start, const char *n | |
32 | && (!is_path || name[len] != ':')) | |
33 | return 0; | |
34 | ||
35 | - if (__builtin_expect (secure, 0) | |
36 | - && ((name[len] != '\0' && (!is_path || name[len] != ':')) | |
37 | - || (name != start + 1 && (!is_path || name[-2] != ':')))) | |
38 | - return 0; | |
39 | - | |
40 | return len; | |
41 | } | |
42 | ||
43 | @@ -218,13 +212,10 @@ _dl_dst_count (const char *name, int is_ | |
44 | { | |
45 | size_t len; | |
46 | ||
47 | - /* $ORIGIN is not expanded for SUID/GUID programs (except if it | |
48 | - is $ORIGIN alone) and it must always appear first in path. */ | |
49 | ++name; | |
50 | - if ((len = is_dst (start, name, "ORIGIN", is_path, | |
51 | - INTUSE(__libc_enable_secure))) != 0 | |
52 | - || (len = is_dst (start, name, "PLATFORM", is_path, 0)) != 0 | |
53 | - || (len = is_dst (start, name, "LIB", is_path, 0)) != 0) | |
54 | + if ((len = is_dst (start, name, "ORIGIN", is_path)) != 0 | |
55 | + || (len = is_dst (start, name, "PLATFORM", is_path)) != 0 | |
56 | + || (len = is_dst (start, name, "LIB", is_path)) != 0) | |
57 | ++cnt; | |
58 | ||
59 | name = strchr (name + len, '$'); | |
60 | @@ -256,9 +247,16 @@ _dl_dst_substitute (struct link_map *l, | |
61 | size_t len; | |
62 | ||
63 | ++name; | |
64 | - if ((len = is_dst (start, name, "ORIGIN", is_path, | |
65 | - INTUSE(__libc_enable_secure))) != 0) | |
66 | + if ((len = is_dst (start, name, "ORIGIN", is_path)) != 0) | |
67 | { | |
68 | + /* $ORIGIN is not expanded for SUID/GUID programs | |
69 | + (except if it is $ORIGIN alone) and it must always | |
70 | + appear first in path. */ | |
71 | + if (__builtin_expect (INTUSE(__libc_enable_secure), 0) | |
72 | + && ((name[len] != '\0' && (!is_path || name[len] != ':')) | |
73 | + || (name != start + 1 && (!is_path || name[-2] != ':')))) | |
74 | + repl = (const char *) -1; | |
75 | + else | |
76 | #ifndef SHARED | |
77 | if (l == NULL) | |
78 | repl = _dl_get_origin (); | |
79 | @@ -266,9 +264,9 @@ _dl_dst_substitute (struct link_map *l, | |
80 | #endif | |
81 | repl = l->l_origin; | |
82 | } | |
83 | - else if ((len = is_dst (start, name, "PLATFORM", is_path, 0)) != 0) | |
84 | + else if ((len = is_dst (start, name, "PLATFORM", is_path)) != 0) | |
85 | repl = GLRO(dl_platform); | |
86 | - else if ((len = is_dst (start, name, "LIB", is_path, 0)) != 0) | |
87 | + else if ((len = is_dst (start, name, "LIB", is_path)) != 0) | |
88 | repl = DL_DST_LIB; | |
89 | ||
90 | if (repl != NULL && repl != (const char *) -1) | |
91 | @@ -284,6 +282,10 @@ _dl_dst_substitute (struct link_map *l, | |
92 | name += len; | |
93 | while (*name != '\0' && (!is_path || *name != ':')) | |
94 | ++name; | |
95 | + /* Also skip following colon if this is the first rpath | |
96 | + element, but keep an empty element at the end. */ | |
97 | + if (wp == result && is_path && *name == ':' && name[1] != '\0') | |
98 | + ++name; | |
99 | } | |
100 | else | |
101 | /* No DST we recognize. */ | |
102 | @@ -310,7 +312,7 @@ _dl_dst_substitute (struct link_map *l, | |
103 | belonging to the map is loaded. In this case the path element | |
104 | containing $ORIGIN is left out. */ | |
105 | static char * | |
106 | -expand_dynamic_string_token (struct link_map *l, const char *s) | |
107 | +expand_dynamic_string_token (struct link_map *l, const char *s, int is_path) | |
108 | { | |
109 | /* We make two runs over the string. First we determine how large the | |
110 | resulting string is and then we copy it over. Since this is no | |
111 | @@ -321,7 +323,7 @@ expand_dynamic_string_token (struct link | |
112 | char *result; | |
113 | ||
114 | /* Determine the number of DST elements. */ | |
115 | - cnt = DL_DST_COUNT (s, 1); | |
116 | + cnt = DL_DST_COUNT (s, is_path); | |
117 | ||
118 | /* If we do not have to replace anything simply copy the string. */ | |
119 | if (__builtin_expect (cnt, 0) == 0) | |
120 | @@ -335,7 +337,7 @@ expand_dynamic_string_token (struct link | |
121 | if (result == NULL) | |
122 | return NULL; | |
123 | ||
124 | - return _dl_dst_substitute (l, s, result, 1); | |
125 | + return _dl_dst_substitute (l, s, result, is_path); | |
126 | } | |
127 | ||
128 | ||
129 | @@ -551,13 +553,21 @@ decompose_rpath (struct r_search_path_st | |
130 | ||
131 | /* Make a writable copy. At the same time expand possible dynamic | |
132 | string tokens. */ | |
133 | - copy = expand_dynamic_string_token (l, rpath); | |
134 | + copy = expand_dynamic_string_token (l, rpath, 1); | |
135 | if (copy == NULL) | |
136 | { | |
137 | errstring = N_("cannot create RUNPATH/RPATH copy"); | |
138 | goto signal_error; | |
139 | } | |
140 | ||
141 | + /* Ignore empty rpaths. */ | |
142 | + if (*copy == 0) | |
143 | + { | |
144 | + free (copy); | |
145 | + sps->dirs = (char *) -1; | |
146 | + return false; | |
147 | + } | |
148 | + | |
149 | /* Count the number of necessary elements in the result array. */ | |
150 | nelems = 0; | |
151 | for (cp = copy; *cp != '\0'; ++cp) | |
152 | @@ -2176,7 +2186,7 @@ _dl_map_object (struct link_map *loader, | |
153 | { | |
154 | /* The path may contain dynamic string tokens. */ | |
155 | realname = (loader | |
156 | - ? expand_dynamic_string_token (loader, name) | |
157 | + ? expand_dynamic_string_token (loader, name, 0) | |
158 | : local_strdup (name)); | |
159 | if (realname == NULL) | |
160 | fd = -1; |