Annotation of /trunk/xorg-server/patches/xorg-server-1.17.1-CVE-2015-3164.patch
Parent Directory | Revision Log
Revision 2576 -
(hide annotations)
(download)
Mon Jun 15 13:02:17 2015 UTC (9 years, 3 months ago) by niro
File size: 8247 byte(s)
Mon Jun 15 13:02:17 2015 UTC (9 years, 3 months ago) by niro
File size: 8247 byte(s)
-fixed garbage patches
1 | niro | 2576 | From c4534a38b68aa07fb82318040dc8154fb48a9588 Mon Sep 17 00:00:00 2001 |
2 | From: Ray Strode <rstrode@redhat.com> | ||
3 | niro | 2575 | Date: Tue, 5 May 2015 16:43:42 -0400 |
4 | Subject: xwayland: Enable access control on open sockets [CVE-2015-3164 1/3] | ||
5 | |||
6 | Xwayland currently allows wide-open access to the X sockets | ||
7 | it listens on, ignoring Xauth access control. | ||
8 | |||
9 | This commit makes sure to enable access control on the sockets, | ||
10 | so one user can't snoop on another user's X-over-wayland | ||
11 | applications. | ||
12 | |||
13 | niro | 2576 | Signed-off-by: Ray Strode <rstrode@redhat.com> |
14 | Reviewed-by: Daniel Stone <daniels@collabora.com> | ||
15 | Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> | ||
16 | Signed-off-by: Keith Packard <keithp@keithp.com> | ||
17 | niro | 2575 | |
18 | diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c | ||
19 | index 7e8d667..c5bee77 100644 | ||
20 | niro | 2576 | --- a/hw/xwayland/xwayland.c |
21 | +++ b/hw/xwayland/xwayland.c | ||
22 | @@ -483,7 +483,7 @@ listen_on_fds(struct xwl_screen *xwl_screen) | ||
23 | niro | 2575 | int i; |
24 | |||
25 | niro | 2576 | for (i = 0; i < xwl_screen->listen_fd_count; i++) |
26 | - ListenOnOpenFD(xwl_screen->listen_fds[i], TRUE); | ||
27 | + ListenOnOpenFD(xwl_screen->listen_fds[i], FALSE); | ||
28 | niro | 2575 | } |
29 | |||
30 | static void | ||
31 | niro | 2576 | -- |
32 | niro | 2575 | cgit v0.10.2 |
33 | From 4b4b9086d02b80549981d205fb1f495edc373538 Mon Sep 17 00:00:00 2001 | ||
34 | niro | 2576 | From: Ray Strode <rstrode@redhat.com> |
35 | niro | 2575 | Date: Tue, 5 May 2015 16:43:43 -0400 |
36 | Subject: os: support new implicit local user access mode [CVE-2015-3164 2/3] | ||
37 | |||
38 | If the X server is started without a '-auth' argument, then | ||
39 | it gets started wide open to all local users on the system. | ||
40 | |||
41 | This isn't a great default access model, but changing it in | ||
42 | Xorg at this point would break backward compatibility. | ||
43 | |||
44 | Xwayland, on the other hand is new, and much more targeted | ||
45 | in scope. It could, in theory, be changed to allow the much | ||
46 | niro | 2576 | more secure default of a "user who started X server can connect |
47 | clients to that server." | ||
48 | niro | 2575 | |
49 | This commit paves the way for that change, by adding a mechanism | ||
50 | for DDXs to opt-in to that behavior. They merely need to call | ||
51 | |||
52 | LocalAccessScopeUser() | ||
53 | |||
54 | in their init functions. | ||
55 | |||
56 | A subsequent commit will add that call for Xwayland. | ||
57 | |||
58 | niro | 2576 | Signed-off-by: Ray Strode <rstrode@redhat.com> |
59 | Reviewed-by: Daniel Stone <daniels@collabora.com> | ||
60 | Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> | ||
61 | Signed-off-by: Keith Packard <keithp@keithp.com> | ||
62 | niro | 2575 | |
63 | diff --git a/include/os.h b/include/os.h | ||
64 | index 6638c84..b2b96c8 100644 | ||
65 | niro | 2576 | --- a/include/os.h |
66 | +++ b/include/os.h | ||
67 | @@ -431,11 +431,28 @@ extern _X_EXPORT void | ||
68 | niro | 2575 | ResetHosts(const char *display); |
69 | |||
70 | extern _X_EXPORT void | ||
71 | niro | 2576 | +EnableLocalAccess(void); |
72 | + | ||
73 | +extern _X_EXPORT void | ||
74 | +DisableLocalAccess(void); | ||
75 | + | ||
76 | +extern _X_EXPORT void | ||
77 | niro | 2575 | EnableLocalHost(void); |
78 | |||
79 | extern _X_EXPORT void | ||
80 | DisableLocalHost(void); | ||
81 | |||
82 | niro | 2576 | +#ifndef NO_LOCAL_CLIENT_CRED |
83 | +extern _X_EXPORT void | ||
84 | +EnableLocalUser(void); | ||
85 | + | ||
86 | +extern _X_EXPORT void | ||
87 | +DisableLocalUser(void); | ||
88 | + | ||
89 | +extern _X_EXPORT void | ||
90 | +LocalAccessScopeUser(void); | ||
91 | +#endif | ||
92 | + | ||
93 | niro | 2575 | extern _X_EXPORT void |
94 | AccessUsingXdmcp(void); | ||
95 | |||
96 | diff --git a/os/access.c b/os/access.c | ||
97 | index 8fa028e..75e7a69 100644 | ||
98 | niro | 2576 | --- a/os/access.c |
99 | +++ b/os/access.c | ||
100 | @@ -102,6 +102,10 @@ SOFTWARE. | ||
101 | #include <sys/ioctl.h> | ||
102 | #include <ctype.h> | ||
103 | niro | 2575 | |
104 | niro | 2576 | +#ifndef NO_LOCAL_CLIENT_CRED |
105 | +#include <pwd.h> | ||
106 | +#endif | ||
107 | + | ||
108 | niro | 2575 | #if defined(TCPCONN) || defined(STREAMSCONN) |
109 | niro | 2576 | #include <netinet/in.h> |
110 | niro | 2575 | #endif /* TCPCONN || STREAMSCONN */ |
111 | niro | 2576 | @@ -225,6 +229,13 @@ static int LocalHostEnabled = FALSE; |
112 | niro | 2575 | static int LocalHostRequested = FALSE; |
113 | static int UsingXdmcp = FALSE; | ||
114 | |||
115 | niro | 2576 | +static enum { |
116 | + LOCAL_ACCESS_SCOPE_HOST = 0, | ||
117 | +#ifndef NO_LOCAL_CLIENT_CRED | ||
118 | + LOCAL_ACCESS_SCOPE_USER, | ||
119 | +#endif | ||
120 | +} LocalAccessScope; | ||
121 | + | ||
122 | niro | 2575 | /* FamilyServerInterpreted implementation */ |
123 | static Bool siAddrMatch(int family, void *addr, int len, HOST * host, | ||
124 | ClientPtr client); | ||
125 | niro | 2576 | @@ -237,6 +248,21 @@ static void siTypesInitialize(void); |
126 | niro | 2575 | */ |
127 | |||
128 | void | ||
129 | niro | 2576 | +EnableLocalAccess(void) |
130 | +{ | ||
131 | + switch (LocalAccessScope) { | ||
132 | + case LOCAL_ACCESS_SCOPE_HOST: | ||
133 | + EnableLocalHost(); | ||
134 | + break; | ||
135 | +#ifndef NO_LOCAL_CLIENT_CRED | ||
136 | + case LOCAL_ACCESS_SCOPE_USER: | ||
137 | + EnableLocalUser(); | ||
138 | + break; | ||
139 | +#endif | ||
140 | + } | ||
141 | +} | ||
142 | + | ||
143 | +void | ||
144 | niro | 2575 | EnableLocalHost(void) |
145 | { | ||
146 | if (!UsingXdmcp) { | ||
147 | niro | 2576 | @@ -249,6 +275,21 @@ EnableLocalHost(void) |
148 | niro | 2575 | * called when authorization is enabled to keep us secure |
149 | */ | ||
150 | void | ||
151 | niro | 2576 | +DisableLocalAccess(void) |
152 | +{ | ||
153 | + switch (LocalAccessScope) { | ||
154 | + case LOCAL_ACCESS_SCOPE_HOST: | ||
155 | + DisableLocalHost(); | ||
156 | + break; | ||
157 | +#ifndef NO_LOCAL_CLIENT_CRED | ||
158 | + case LOCAL_ACCESS_SCOPE_USER: | ||
159 | + DisableLocalUser(); | ||
160 | + break; | ||
161 | +#endif | ||
162 | + } | ||
163 | +} | ||
164 | + | ||
165 | +void | ||
166 | niro | 2575 | DisableLocalHost(void) |
167 | { | ||
168 | HOST *self; | ||
169 | niro | 2576 | @@ -262,6 +303,74 @@ DisableLocalHost(void) |
170 | niro | 2575 | } |
171 | } | ||
172 | |||
173 | niro | 2576 | +#ifndef NO_LOCAL_CLIENT_CRED |
174 | +static int GetLocalUserAddr(char **addr) | ||
175 | +{ | ||
176 | + static const char *type = "localuser"; | ||
177 | + static const char delimiter = '\0'; | ||
178 | + static const char *value; | ||
179 | + struct passwd *pw; | ||
180 | + int length = -1; | ||
181 | + | ||
182 | + pw = getpwuid(getuid()); | ||
183 | + | ||
184 | + if (pw == NULL || pw->pw_name == NULL) | ||
185 | + goto out; | ||
186 | + | ||
187 | + value = pw->pw_name; | ||
188 | + | ||
189 | + length = asprintf(addr, "%s%c%s", type, delimiter, value); | ||
190 | + | ||
191 | + if (length == -1) { | ||
192 | + goto out; | ||
193 | + } | ||
194 | + | ||
195 | + /* Trailing NUL */ | ||
196 | + length++; | ||
197 | + | ||
198 | +out: | ||
199 | + return length; | ||
200 | +} | ||
201 | + | ||
202 | +void | ||
203 | +EnableLocalUser(void) | ||
204 | +{ | ||
205 | + char *addr = NULL; | ||
206 | + int length = -1; | ||
207 | + | ||
208 | + length = GetLocalUserAddr(&addr); | ||
209 | + | ||
210 | + if (length == -1) | ||
211 | + return; | ||
212 | + | ||
213 | + NewHost(FamilyServerInterpreted, addr, length, TRUE); | ||
214 | + | ||
215 | + free(addr); | ||
216 | +} | ||
217 | + | ||
218 | +void | ||
219 | +DisableLocalUser(void) | ||
220 | +{ | ||
221 | + char *addr = NULL; | ||
222 | + int length = -1; | ||
223 | + | ||
224 | + length = GetLocalUserAddr(&addr); | ||
225 | + | ||
226 | + if (length == -1) | ||
227 | + return; | ||
228 | + | ||
229 | + RemoveHost(NULL, FamilyServerInterpreted, length, addr); | ||
230 | + | ||
231 | + free(addr); | ||
232 | +} | ||
233 | + | ||
234 | +void | ||
235 | +LocalAccessScopeUser(void) | ||
236 | +{ | ||
237 | + LocalAccessScope = LOCAL_ACCESS_SCOPE_USER; | ||
238 | +} | ||
239 | +#endif | ||
240 | + | ||
241 | niro | 2575 | /* |
242 | * called at init time when XDMCP will be used; xdmcp always | ||
243 | * adds local hosts manually when needed | ||
244 | diff --git a/os/auth.c b/os/auth.c | ||
245 | index 5fcb538..7da6fc6 100644 | ||
246 | niro | 2576 | --- a/os/auth.c |
247 | +++ b/os/auth.c | ||
248 | @@ -181,11 +181,11 @@ CheckAuthorization(unsigned int name_length, | ||
249 | niro | 2575 | |
250 | /* | ||
251 | * If the authorization file has at least one entry for this server, | ||
252 | niro | 2576 | - * disable local host access. (loadauth > 0) |
253 | + * disable local access. (loadauth > 0) | ||
254 | niro | 2575 | * |
255 | * If there are zero entries (either initially or when the | ||
256 | * authorization file is later reloaded), or if a valid | ||
257 | niro | 2576 | - * authorization file was never loaded, enable local host access. |
258 | + * authorization file was never loaded, enable local access. | ||
259 | niro | 2575 | * (loadauth == 0 || !loaded) |
260 | * | ||
261 | * If the authorization file was loaded initially (with valid | ||
262 | niro | 2576 | @@ -194,11 +194,11 @@ CheckAuthorization(unsigned int name_length, |
263 | niro | 2575 | */ |
264 | |||
265 | niro | 2576 | if (loadauth > 0) { |
266 | - DisableLocalHost(); /* got at least one */ | ||
267 | + DisableLocalAccess(); /* got at least one */ | ||
268 | niro | 2575 | loaded = TRUE; |
269 | } | ||
270 | else if (loadauth == 0 || !loaded) | ||
271 | niro | 2576 | - EnableLocalHost(); |
272 | + EnableLocalAccess(); | ||
273 | niro | 2575 | } |
274 | if (name_length) { | ||
275 | niro | 2576 | for (i = 0; i < NUM_AUTHORIZATION; i++) { |
276 | -- | ||
277 | niro | 2575 | cgit v0.10.2 |
278 | From 76636ac12f2d1dbdf7be08222f80e7505d53c451 Mon Sep 17 00:00:00 2001 | ||
279 | niro | 2576 | From: Ray Strode <rstrode@redhat.com> |
280 | niro | 2575 | Date: Tue, 5 May 2015 16:43:44 -0400 |
281 | Subject: xwayland: default to local user if no xauth file given. | ||
282 | [CVE-2015-3164 3/3] | ||
283 | |||
284 | niro | 2576 | Right now if "-auth" isn't passed on the command line, we let |
285 | niro | 2575 | any user on the system connect to the Xwayland server. |
286 | |||
287 | That's clearly suboptimal, given Xwayland is generally designed | ||
288 | to be used by one user at a time. | ||
289 | |||
290 | This commit changes the behavior, so only the user who started the | ||
291 | X server can connect clients to it. | ||
292 | |||
293 | niro | 2576 | Signed-off-by: Ray Strode <rstrode@redhat.com> |
294 | Reviewed-by: Daniel Stone <daniels@collabora.com> | ||
295 | Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> | ||
296 | Signed-off-by: Keith Packard <keithp@keithp.com> | ||
297 | niro | 2575 | |
298 | diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c | ||
299 | index c5bee77..bc92beb 100644 | ||
300 | niro | 2576 | --- a/hw/xwayland/xwayland.c |
301 | +++ b/hw/xwayland/xwayland.c | ||
302 | @@ -702,4 +702,6 @@ InitOutput(ScreenInfo * screen_info, int argc, char **argv) | ||
303 | niro | 2575 | if (AddScreen(xwl_screen_init, argc, argv) == -1) { |
304 | niro | 2576 | FatalError("Couldn't add screen\n"); |
305 | niro | 2575 | } |
306 | niro | 2576 | + |
307 | + LocalAccessScopeUser(); | ||
308 | niro | 2575 | } |
309 | niro | 2576 | -- |
310 | niro | 2575 | cgit v0.10.2 |
311 |