1 TITLE: Make xconsole work (v.02)
3 AUTHOR: Matthias S. Benkmann <m.s.b@gmx.net>
6 xconsole gave me a lot of trouble. It wouldn't work when started
7 as a normal user, even when made setuid root. And when reading
8 from /dev/console (default) it intercepted keystrokes intended for
9 xterm windows. If you have the same problems, read this hint.
13 I checked out a SuSE system and saw that they did not have xconsole read
14 from /dev/console. Instead is was set up to read from a FIFO /dev/xconsole that
15 was fed by syslogd. This has the advantage that you
16 can use syslog.conf to control exactly which messages you want to be displayed
19 To set it up like this do the following:
21 1. Create the /dev/xconsole FIFO
24 chmod 640 /dev/xconsole
25 chown root.tty /dev/xconsole
27 2. Tell syslogd to write messages to /dev/xconsole by adding a line like
28 the following to /etc/syslog.conf
30 *.err;auth,authpriv.none |/dev/xconsole
32 This will write all messages with priority err or higher to /dev/xconsole,
33 with the exception of auth and authpriv messages (because these may contain
37 Now you can start xconsole like this
39 xconsole -file /dev/xconsole
41 and it will use the FIFO.
43 The above fixes the strange keystroke-grabbing problems. There still remains
44 the problem that xconsole only works when started by root. Neither making it
45 setuid root nor setgid tty will help. A look at the source code reveals the
46 reason for this. xconsole uses the access() function to test if it can access
47 the file it's told to read from. Unfortunately access() only checks the
48 real uid and not the effective uid of the process, and setuid root only
49 changes the effective uid. The reason for this is probably that otherwise
50 a setuid root xconsole could be used to spy on other users.
51 To work around this issue I wrote the following program:
53 ------------------- begin startxconsole.c -----------------------------------
54 #include <sys/types.h>
70 /* set XAUTHORITY to real home directory of user instead of allowing
71 user to specify something */
72 pw=getpwuid(getuid());
73 if (pw==NULL) {perror("getpwuid"); return 1;};
74 xauth=malloc(strlen(pw->pw_dir)+128);
75 if (xauth==NULL) {perror("malloc"); return 1;};
76 strcpy(xauth,"XAUTHORITY=");
77 strcat(xauth,pw->pw_dir);
78 strcat(xauth,"/.Xauthority");
80 /* empty environment (except for std path, DISPLAY and XAUTHORITY) */
81 env[0]="PATH=/bin:/usr/bin";
82 env[1]="DISPLAY=:0.0";
86 /* reset signal handlers to default */
87 for (i = 1; i < NSIG; i++) signal (i, SIG_DFL);
89 /* stdin="/dev/null" (to prevent users from passing insecure data) */
91 if ( open("/dev/null",O_RDONLY) != 0 )
93 fprintf(stderr,"Unable to redirect /dev/null -> stdin\n");
97 /* close all fds except stdin,stdout,stderr (just for paranoia) */
99 for (fd = 3; fd < i; ++fd) close (fd);
101 /* set real ids to effective ids */
102 setreuid(geteuid(),geteuid());
103 setregid(getegid(),getegid());
104 execle("/usr/X11R6/bin/xconsole","xconsole","-file","/dev/xconsole",
105 "-notify","-verbose","-geometry","-0-0",NULL,env);
106 perror("/usr/X11R6/bin/xconsole");
109 ------------------- end startxconsole.c -----------------------------------
113 gcc -W -Wall -O2 -o startxconsole startxconsole.c
116 startxconsole makes setuid and setgid behave as expected. So you can do
119 chgrp tty startxconsole
120 chmod g+s startxconsole
122 and you can call startxconsole as a normal user (you should probably put
123 it into xinitrc) and it will start up xconsole.
124 Note that for security reasons, startxconsole has the command line for
125 xconsole hardwired. That way users can't pass their own arguments to xconsole.
126 If they were allowed to pass their own arguments they could specify some
127 other user's tty device as -file to spy on this user.
128 In addition to this startxconsole always sets the location of the .Xauthority
129 file (via the XAUTHORITY environment variable) to <home>/.Xauthority where
130 <home> is the home directory of the calling user. This makes sure that a
131 user can't use XAUTHORITY to cause a read access to a file not belonging to
132 him. DISPLAY is always set to :0.0.
133 All other environment variables are removed (or rather, not passed to xconsole),
134 signal handlers are reset to the default, stdin is set to /dev/null and all
135 other file descriptors except for stdout and stderr are closed. This should
136 eliminate every possibility for the user to pass insecure data to xconsole.