]> git.pld-linux.org Git - packages/X11.git/blob - XFree86-Xwrapper.patch
- cleanup
[packages/X11.git] / XFree86-Xwrapper.patch
1 diff -urN xc.orig/config/cf/Server.tmpl xc/config/cf/Server.tmpl
2 --- xc.orig/config/cf/Server.tmpl       Mon Dec 30 15:52:30 2002
3 +++ xc/config/cf/Server.tmpl    Mon Dec 30 17:31:51 2002
4 @@ -25,8 +25,14 @@
5  #ifndef DoThreadedServer
6  #define DoThreadedServer NO
7  #endif
8 +#ifndef XserverNeedsSetUID
9 +#define XserverNeedsSetUID NO
10 +#endif
11 +#ifndef UseXserverWrapper
12 +#define UseXserverWrapper XserverNeedsSetUID
13 +#endif
14  #ifndef InstallServerSetUID
15 -#define InstallServerSetUID NO
16 +#define InstallServerSetUID (XserverNeedsSetUID && !UseXserverWrapper)
17  #endif
18  
19  #ifdef CrossCompileDir
20 diff -urN xc.orig/config/cf/xf86site.def xc/config/cf/xf86site.def
21 --- xc.orig/config/cf/xf86site.def      Mon Dec 30 15:52:31 2002
22 +++ xc/config/cf/xf86site.def   Mon Dec 30 17:37:06 2002
23 @@ -69,14 +69,15 @@
24   */
25  
26  /*
27 - * If you only run the X server under xdm the X servers don't need to be
28 - * installed SetUID, and you may comment out the lines below.  If you run
29 - * the servers by hand (with xinit or startx), then they do need to be
30 - * installed SetUID on most platforms.
31 + * The X servers need to run as root on most OSs.  We're now using a
32 + * wrapper in that case, but we still need to make it known that the
33 + * servers need SetUID.  When only using xdm, this (and the wrapper)
34 + * are not required.  Disabling this automatically disables use of the
35 + * wrapper.
36   *
37 - * Consult your system administrator before making the X server setuid.
38 + * If you're only starting the Xservers with xdm set this to NO
39   *
40 -#define InstallXserverSetUID   NO
41 +#define XserverNeedsSetUID    NO
42   */
43  
44  
45 diff -urN xc.orig/config/cf/xfree86.cf xc/config/cf/xfree86.cf
46 --- xc.orig/config/cf/xfree86.cf        Mon Dec 30 15:52:31 2002
47 +++ xc/config/cf/xfree86.cf     Mon Dec 30 17:31:51 2002
48 @@ -1104,12 +1104,15 @@
49  #endif
50  
51  /*
52 - * The default is to install the X servers setuid-root on most OSs.
53 - * It the servers are only started by xdm, they should not be setuid-root.
54 + * The X servers need to run as root on most OSs.  We're now using a
55 + * wrapper in that case, but we still need to make it known that the
56 + * servers need SetUID.  When only using xdm, this (and the wrapper)
57 + * are not required.  Disabling this automatically disables use of the
58 + * wrapper.
59   */
60  #if !defined(i386MachArchitecture) && !defined(OS2Architecture)
61 -# ifndef InstallXserverSetUID
62 -#  define InstallXserverSetUID YES
63 +# ifndef XserverNeedsSetUID
64 +#  define XserverNeedsSetUID   YES
65  # endif
66  #endif
67  
68 diff -urN xc.orig/programs/Xserver/Imakefile xc/programs/Xserver/Imakefile
69 --- xc.orig/programs/Xserver/Imakefile  Mon Dec 30 15:53:22 2002
70 +++ xc/programs/Xserver/Imakefile       Mon Dec 30 17:31:51 2002
71 @@ -4,11 +4,6 @@
72   */
73  XCOMM $XFree86: xc/programs/Xserver/Imakefile,v 3.275 2002/12/21 00:19:11 torrey Exp $
74  
75 -#ifndef InstallXserverSetUID
76 -#define InstallXserverSetUID NO
77 -#endif
78 -#define InstallServerSetUID InstallXserverSetUID
79 -
80  #include <Server.tmpl>
81  
82  #ifdef XFree86Version
83 @@ -1146,6 +1141,12 @@
84  #endif /* XnestServer */
85  
86  
87 +#if UseXserverWrapper
88 +all:: Xwrapper
89 +SetUIDProgramTarget(Xwrapper,os/wrapper.o,NullParameter,$(SERVERPAMLIBRARIES),NullParameter)
90 +InstallProgramWithFlags(Xwrapper,$(BINDIR),$(INSTUIDFLAGS))
91 +#endif
92 +
93  #if defined(XnonServer) && XnonServer
94  XCOMM
95  XCOMM non server, just compile sources for build test
96 diff -urN xc.orig/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c
97 --- xc.orig/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c     Mon Dec 30 15:53:52 2002
98 +++ xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c  Mon Dec 30 17:31:51 2002
99 @@ -66,7 +66,10 @@
100         /* check if we're run with euid==0 */
101         if (geteuid() != 0)
102         {
103 -           FatalError("xf86OpenConsole: Server must be suid root\n");
104 +           FatalError("xf86OpenConsole: Server must be running with root "
105 +               "permissions\n"
106 +               "You should be using Xwrapper to start the server or xdm.\n"
107 +               "We strongly advise against making the server SUID root!\n");
108         }
109  
110         /*
111 --- xc/programs/Xserver/os/Imakefile.orig       2006-02-19 16:51:31.000000000 +0100
112 +++ xc/programs/Xserver/os/Imakefile    2006-07-19 21:30:56.576028250 +0200
113 @@ -239,6 +241,14 @@
114  SpecialCObjectRule(oscolor,$(ICONFIGFILES),$(DBM_DEFINES))
115  #endif
116  
117 +#if UseXserverWrapper && XF86Server
118 +AllTarget(wrapper.o)
119 +
120 +       WRAPPER_DEFINES = -DXSERVER_PATH=\"/etc/X11/X\" $(PAMDEFINES)
121 +
122 +SpecialCObjectRule(wrapper,NullParameter,$(WRAPPER_DEFINES))
123 +#endif
124 +
125  #if HasKrb5
126  LinkSourceFile(k5encode.c,$(XAUTHSRC))
127  #endif
128 diff -urN xc.orig/programs/Xserver/os/wrapper.c xc/programs/Xserver/os/wrapper.c
129 --- xc.orig/programs/Xserver/os/wrapper.c       Thu Jan  1 01:00:00 1970
130 +++ xc/programs/Xserver/os/wrapper.c    Mon Dec 30 17:31:52 2002
131 @@ -0,0 +1,304 @@
132 +/*
133 + * X server wrapper.
134 + *
135 + * This wrapper makes some sanity checks on the command line arguments
136 + * and environment variables when run with euid == 0 && euid != uid.
137 + * If the checks fail, the wrapper exits with a message.
138 + * If they succeed, it exec's the Xserver.
139 + */
140 +
141 +/*
142 + * Copyright (c) 1998 by The XFree86 Project, Inc.  All Rights Reserved.
143 + *
144 + * Permission is hereby granted, free of charge, to any person obtaining
145 + * a copy of this software and associated documentation files (the
146 + * "Software"), to deal in the Software without restriction, including
147 + * without limitation the rights to use, copy, modify, merge, publish,
148 + * distribute, sublicense, and/or sell copies of the Software, and to
149 + * permit persons to whom the Software is furnished to do so, subject
150 + * to the following conditions:
151 + *
152 + * The above copyright notice and this permission notice shall be included
153 + * in all copies or substantial portions of the Software.
154 + *
155 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
156 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
157 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
158 + * IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES
159 + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
160 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
161 + * OR OTHER DEALINGS IN THE SOFTWARE.
162 + *
163 + * Except as contained in this notice, the name of the XFree86 Project
164 + * shall not be used in advertising or otherwise to promote the sale,
165 + * use or other dealings in this Software without prior written
166 + * authorization from the XFree86 Project.
167 + */
168 +
169 +/* $XFree86: xc/programs/Xserver/os/wrapper.c,v 1.1.2.5 1998/02/27 15:28:59 dawes Exp $ */
170 +
171 +/* This is normally set in the Imakefile */
172 +#ifndef XSERVER_PATH
173 +#define XSERVER_PATH   "/etc/X11/X"
174 +#endif
175 +
176 +#include <stdio.h>
177 +#include <stdlib.h>
178 +#include <string.h>
179 +#include <errno.h>
180 +#include <unistd.h>
181 +#include <sys/types.h>
182 +#ifdef USE_PAM
183 +#include <security/pam_appl.h>
184 +#include <security/pam_misc.h>
185 +#include <pwd.h>
186 +#endif /* USE_PAM */
187 +
188 +/* Neither of these should be required for XFree86 3.3.2 */
189 +#ifndef REJECT_CONFIG
190 +#define REJECT_CONFIG 0
191 +#endif
192 +#ifndef REJECT_XKBDIR
193 +#define REJECT_XKBDIR 0
194 +#endif
195 +
196 +/* Consider LD* variables insecure ? */
197 +#ifndef REMOVE_ENV_LD
198 +#define REMOVE_ENV_LD 1
199 +#endif
200 +
201 +/* Remove long environment variables? */
202 +#ifndef REMOVE_LONG_ENV
203 +#define REMOVE_LONG_ENV 1
204 +#endif
205 +
206 +/* Check args and env only if running setuid (euid == 0 && euid != uid) ? */
207 +#ifndef CHECK_EUID
208 +#define CHECK_EUID 1
209 +#endif
210 +
211 +/*
212 + * Maybe the locale can be faked to make isprint(3) report that everything
213 + * is printable?  Avoid it by default.
214 + */
215 +#ifndef USE_ISPRINT
216 +#define USE_ISPRINT 0
217 +#endif
218 +
219 +#define MAX_ARG_LENGTH         128
220 +#define MAX_ENV_LENGTH         256
221 +#define MAX_ENV_PATH_LENGTH    2048
222 +
223 +#if USE_ISPRINT
224 +#include <ctype.h>
225 +#define checkPrintable(c) isprint(c)
226 +#else
227 +#define checkPrintable(c) (((c) & 0x7f) >= 0x20 && ((c) & 0x7f) != 0x7f)
228 +#endif
229 +
230 +enum BadCode {
231 +    NotBad = 0,
232 +    UnsafeArg,
233 +    ArgTooLong,
234 +    UnprintableArg,
235 +    EnvTooLong,
236 +    InternalError,
237 +#ifdef USE_PAM
238 +    PamFailed,
239 +    PamAuthFailed,
240 +#endif /* USE_PAM */
241 +};
242 +
243 +#define ARGMSG \
244 +    "\nIf the arguments used are valid, and have been rejected incorrectly\n" \
245 +      "please send details of the arguments and why they are valid to\n" \
246 +      "XFree86@XFree86.org.  In the meantime, you can start the Xserver as\n" \
247 +      "the \"super user\" (root).\n"   
248 +
249 +#define ENVMSG \
250 +    "\nIf the environment is valid, and have been rejected incorrectly\n" \
251 +      "please send details of the environment and why it is valid to\n" \
252 +      "XFree86@XFree86.org.  In the meantime, you can start the Xserver as\n" \
253 +      "the \"super user\" (root).\n"
254 +
255 +#ifdef USE_PAM
256 +static struct pam_conv conv = {
257 +    misc_conv,
258 +    NULL
259 +};
260 +#endif /* USE_PAM */
261 +
262 +
263 +int
264 +main(int argc, char **argv, char **envp)
265 +{
266 +    enum BadCode bad = NotBad;
267 +    int i, j;
268 +    char *a, *e;
269 +#ifdef USE_PAM
270 +    pam_handle_t *pamh = NULL;
271 +    struct passwd *pw;
272 +    int retval;
273 +
274 +    pw = getpwuid(getuid());
275 +    if (pw == NULL) {
276 +       bad = InternalError;
277 +    }
278 +
279 +    if (!bad) {
280 +       retval = pam_start("xserver", pw->pw_name, &conv, &pamh);
281 +       if (retval != PAM_SUCCESS)
282 +           bad = PamFailed;
283 +    }
284 +
285 +    if (!bad) {
286 +       retval = pam_authenticate(pamh, 0);
287 +       if (retval != PAM_SUCCESS) {
288 +           pam_end(pamh, retval);
289 +           bad = PamAuthFailed;
290 +       }
291 +    }
292 +
293 +    if (!bad) {
294 +       retval = pam_acct_mgmt(pamh, 0);
295 +       if (retval != PAM_SUCCESS) {
296 +           pam_end(pamh, retval);
297 +           bad = PamAuthFailed;
298 +       }
299 +    }
300 +
301 +    /* this is not a session, so do not do session management */
302 +
303 +    if (!bad) pam_end(pamh, PAM_SUCCESS);
304 +#endif /* USE_PAM */
305 +
306 +#if CHECK_EUID
307 +    if (!bad && geteuid() == 0 && getuid() != geteuid()) {
308 +#else
309 +    if (!bad) {
310 +#endif
311 +       /* Check each argv[] */
312 +       for (i = 1; i < argc; i++) {
313 +
314 +           /* Check for known bad arguments */
315 +#if REJECT_CONFIG
316 +           if (strcmp(argv[i], "-config") == 0) {
317 +               bad = UnsafeArg;
318 +               break;
319 +           }
320 +#endif
321 +#if REJECT_XKBDIR
322 +           if (strcmp(argv[i], "-xkbdir") == 0) {
323 +               bad = UnsafeArg;
324 +               break;
325 +           }
326 +#endif
327 +           if (strlen(argv[i]) > MAX_ARG_LENGTH) {
328 +               bad = ArgTooLong;
329 +               break;
330 +           }
331 +           a = argv[i];
332 +           while (*a) {
333 +               if (checkPrintable(*a) == 0) {
334 +                   bad = UnprintableArg;
335 +                   break;
336 +               }
337 +               a++;
338 +           }
339 +           if (bad)
340 +               break;
341 +       }
342 +       /* Check each envp[] */
343 +       if (!bad)
344 +           for (i = 0; envp[i]; i++) {
345 +
346 +               /* Check for bad environment variables and values */
347 +#if REMOVE_ENV_LD
348 +               while (envp[i] && (strncmp(envp[i], "LD", 2) == 0)) {
349 +                   for (j = i; envp[j]; j++) {
350 +                       envp[j] = envp[j+1];
351 +                   }
352 +               }
353 +#endif   
354 +               if (envp[i] && (strlen(envp[i]) > MAX_ENV_LENGTH)) {
355 +#if REMOVE_LONG_ENV
356 +                   for (j = i; envp[j]; j++) {
357 +                       envp[j] = envp[j+1];
358 +                   }
359 +                   i--;
360 +#else
361 +                   char *eq;
362 +                   int len;
363 +
364 +                   eq = strchr(envp[i], '=');
365 +                   if (!eq)
366 +                       continue;
367 +                   len = eq - envp[i];
368 +                   e = malloc(len + 1);
369 +                   if (!e) {
370 +                       bad = InternalError;
371 +                       break;
372 +                   }
373 +                   strncpy(e, envp[i], len);
374 +                   e[len] = 0;
375 +                   if (len >= 4 &&
376 +                       (strcmp(e + len - 4, "PATH") == 0 ||
377 +                        strcmp(e, "TERMCAP") == 0)) {
378 +                       if (strlen(envp[i]) > MAX_ENV_PATH_LENGTH) {
379 +                           bad = EnvTooLong;
380 +                           break;
381 +                       } else {
382 +                           free(e);
383 +                       }
384 +                   } else {
385 +                       bad = EnvTooLong;
386 +                       break;
387 +                   }
388 +#endif
389 +               }
390 +           }
391 +    }
392 +    switch (bad) {
393 +    case NotBad:
394 +       execve(XSERVER_PATH, argv, envp);
395 +       fprintf(stderr, "execve failed for %s (errno %d)\n", XSERVER_PATH,
396 +               errno);
397 +       break;
398 +    case UnsafeArg:
399 +       fprintf(stderr, "Command line argument number %d is unsafe\n", i);
400 +       fprintf(stderr, ARGMSG);
401 +       break;
402 +    case ArgTooLong:
403 +       fprintf(stderr, "Command line argument number %d is too long\n", i);
404 +       fprintf(stderr, ARGMSG);
405 +       break;
406 +    case UnprintableArg:
407 +       fprintf(stderr, "Command line argument number %d contains unprintable"
408 +               " characters\n", i);
409 +       fprintf(stderr, ARGMSG);
410 +       break;
411 +    case EnvTooLong:
412 +       fprintf(stderr, "Environment variable `%s' is too long\n", e);
413 +       fprintf(stderr, ENVMSG);
414 +       break;
415 +    case InternalError:
416 +       fprintf(stderr, "Internal Error\n");
417 +       break;
418 +#ifdef USE_PAM
419 +    case PamFailed:
420 +       fprintf(stderr, "Authentication System Failure, "
421 +                       "missing or mangled PAM configuration file or module?\n");
422 +       break;
423 +    case PamAuthFailed:
424 +       fprintf(stderr, "PAM authentication failed\n");
425 +       break;
426 +#endif
427 +    default:
428 +       fprintf(stderr, "Unknown error\n");
429 +       fprintf(stderr, ARGMSG);
430 +       fprintf(stderr, ENVMSG);
431 +       break;
432 +    }
433 +    exit(1);
434 +}
435 +
436 diff -urN xc.orig/programs/xinit/startx.cpp xc/programs/xinit/startx.cpp
437 --- xc.orig/programs/xinit/startx.cpp   Mon Dec 30 15:54:10 2002
438 +++ xc/programs/xinit/startx.cpp        Mon Dec 30 17:31:52 2002
439 @@ -53,7 +53,7 @@
440  sysclientrc=XINITDIR/xinitrc
441  sysserverrc=XINITDIR/xserverrc
442  defaultclient=BINDIR/xterm
443 -defaultserver=BINDIR/X
444 +defaultserver=BINDIR/Xwrapper
445  defaultclientargs=""
446  defaultserverargs=""
447  clientargs=""
448 diff -urN xc.orig/programs/xinit/xinit.c xc/programs/xinit/xinit.c
449 --- xc.orig/programs/xinit/xinit.c      Mon Dec 30 15:54:10 2002
450 +++ xc/programs/xinit/xinit.c   Mon Dec 30 17:31:52 2002
451 @@ -146,6 +146,7 @@
452  #define        OK_EXIT         0
453  #define        ERR_EXIT        1
454  
455 +char *default_wrapper = BINDIR "/Xwrapper";
456  char *default_server = "X";
457  char *default_display = ":0";          /* choose most efficient */
458  char *default_client[] = {"xterm", "-geometry", "+1+1", "-n", "login", NULL};
459 @@ -332,7 +333,10 @@
460         if (argc == 0 ||
461  #ifndef __UNIXOS2__
462             (**argv != '/' && **argv != '.')) {
463 -               *sptr++ = default_server;
464 +               if (access(default_wrapper, X_OK) == 0)
465 +                       *sptr++ = default_wrapper;
466 +               else
467 +                       *sptr++ = default_server;
468  #else
469             (**argv != '/' && **argv != '\\' && **argv != '.' &&
470              !(isalpha(**argv) && (*argv)[1]==':'))) {
This page took 0.11058 seconds and 3 git commands to generate.