KDE-3.5.10 hangs on startup!
Andreas Haumer
andreas at xss.co.at
Fri Aug 29 17:57:46 BST 2008
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi!
(I already posted this to kde-devel, but got the hint to
better post it to kde-core-devel)
After upgrade from kde-3.5.9 to kde-3.5.10 I found that
the startup sequence as executed by startkde hangs!
After login using KDM and kdm_greeter I see the following processes:
andreas 2695 0.4 0.0 1972 1028 ? Ss 22:22 0:00 /bin/sh /opt/kde3/bin/startkde
andreas 2737 1.3 0.6 26584 12908 ? S 22:22 0:00 ksplash --nodcop
andreas 2739 0.7 0.3 22900 7872 ? S 22:22 0:00 /opt/kde3/bin/kdeinit --oom-pipe 4 --new-startup +kcminit_startup
andreas 2740 0.0 0.0 0 0 ? Z 22:22 0:00 [start_kdeinit_w] <defunct>
root 2741 0.0 0.0 1188 280 ? S 22:22 0:00 start_kdeinit --new-startup +kcminit_startup
andreas 2742 0.0 0.4 22908 8536 ? Ss 22:22 0:00 /opt/kde3/bin/kdeinit --oom-pipe 4 --new-startup +kcminit_startup
andreas 2743 0.0 0.4 22908 8536 ? S 22:22 0:00 /opt/kde3/bin/kdeinit --oom-pipe 4 --new-startup +kcminit_startup
If I send a SIGUSR1 to the last process (PID 2743) it get's
one step furter:
andreas 2695 0.0 0.0 1972 1028 ? Ss 22:22 0:00 /bin/sh /opt/kde3/bin/startkde
andreas 2739 0.0 0.3 22900 7872 ? S 22:22 0:00 /opt/kde3/bin/kdeinit --oom-pipe 4 --new-startup +kcminit_startup
andreas 2740 0.0 0.0 0 0 ? Z 22:22 0:00 [start_kdeinit_w] <defunct>
root 2741 0.0 0.0 1188 280 ? S 22:22 0:00 start_kdeinit --new-startup +kcminit_startup
andreas 2742 0.0 0.4 23448 8820 ? Ss 22:22 0:00 /opt/kde3/bin/kdeinit --oom-pipe 4 --new-startup +kcminit_startup
andreas 2750 0.0 0.4 23012 8996 ? S 22:24 0:00 kdeinit: dcopserver --nosid
andreas 2752 0.0 0.4 23448 8820 ? S 22:24 0:00 /opt/kde3/bin/kdeinit --oom-pipe 4 --new-startup +kcminit_startup
If I repeat sending the waiting processes a SIGUSR I eventuelly
get a initialized KDE desktop...
2695 ? Ss 0:00 /bin/sh /opt/kde3/bin/startkde
2741 ? S 0:00 start_kdeinit --new-startup +kcminit_startup
2742 ? Ss 0:00 kdeinit Running...
2750 ? S 0:00 kdeinit: dcopserver --nosid
2752 ? S 0:00 kdeinit: klauncher --new-startup
2758 ? S 0:00 kdeinit: kded --new-startup
2765 ? S 0:00 kdeinit: kcminit_startup
2766 ? S 0:00 kwrapper ksmserver
2767 ? S 0:00 kdeinit Running...
It looks like the changes to start_kdeinit.c (from kdelibs)
triggered this behaviour. It seems, the OOM protection doesn't
work right so that all starting processes are hanging in the
reset_oom_protect() method waiting for a SIGUSR1 signal to
come.
The problem is: this signal should be sent by the main method
of start_kdeinit (look at the end, the code which get's executed
by the child process):
~ case 0: /* child, keep privileges and do the privileged work */
~ close( pipes[ 1 ] );
~ for(;;) {
~ pid_t pid = 0;
~ int ret = read( pipes[ 0 ], &pid, sizeof( pid_t ));
~ if( ret < 0 && errno == EINTR )
~ continue;
~ if( ret <= 0 ) /* pipe closed or error, exit */
~ _exit(0);
~ if( pid != 0 ) {
~ if (set_protection( pid, 0 ))
~ kill( pid, SIGUSR1 );
~ }
~ }
The changes from kde 3.5.9 to 3.5.10 makes that signal only be
sent if set_protection() returns a value other than 0:
@@ -145,10 +148,10 @@ int main(int argc, char **argv)
~ if( ret < 0 && errno == EINTR )
~ continue;
~ if( ret <= 0 ) /* pipe closed or error, exit */
- - return 0;
+ _exit(0);
~ if( pid != 0 ) {
- - set_protection( pid, 0 );
- - kill( pid, SIGUSR1 );
+ if (set_protection( pid, 0 ))
+ kill( pid, SIGUSR1 );
~ }
~ }
But look at this:
static int set_protection( pid_t pid, int enable )
{
~ char buf[ 1024 ];
~ int procfile;
~ sprintf( buf, "/proc/%d/oom_adj", pid );
~ if( !enable ) {
~ /* Be paranoid and check that the pid we got from the pipe
~ belongs to this user. */
~ struct stat st;
~ if( lstat( buf, &st ) < 0 || st.st_uid != getuid())
~ return 0;
~ }
~ procfile = open( buf, O_WRONLY );
~ if( procfile >= 0 ) {
~ if( enable )
~ write( procfile, "-5", sizeof( "-5" ));
~ else
~ write( procfile, "0", sizeof( "0" ));
~ close( procfile );
~ }
~ return 1;
}
In my case, set_protection() will always return 0, because
I'm running Linux 2.4 and I do not have the "/proc/%d/oom_adj"
file!
This change in kde 3.5.10 seems to break KDE on older Linux
systems!
Some testing proves my theory: the hangs are due to patches
introduced to start_kdeinit.c by user "mueller" with SVN
revision #801222 at Apr 25th, 2008.
The corresponding log message says:
"fix CVE-2008-1671: integer overflows and arbitrary
process kill vulnerability"
The following change to start_kedinit.c from kdelibs-3.5.10
makes the startup sequence work again:
- --- kdelibs3/kinit/start_kdeinit.c 19 Aug 2008 18:18:12 -0000 1.1.1.3
+++ kdelibs3/kinit/start_kdeinit.c 29 Aug 2008 10:42:15 -0000
@@ -150,8 +150,8 @@
~ if( ret <= 0 ) /* pipe closed or error, exit */
~ _exit(0);
~ if( pid != 0 ) {
- - if (set_protection( pid, 0 ))
- - kill( pid, SIGUSR1 );
+ set_protection( pid, 0 );
+ kill( pid, SIGUSR1 );
~ }
~ }
~ }
Note: this is IMHO not the correct and final fix to solve the
problem, it's merely a prove that my initial theory is correct.
The original patch tried to change the behaviour of start_kdeinit.c
to *not* send a SIGUSR1 signal to just any PID written through a
pipe to the kdeinit process. The original patch is a security patch!
Alas, it breaks things for older Linux kernels, so it should be improved
in a way which fixes the security problem but also works with Linux-2.4!
Comments?
- - andreas
- --
Andreas Haumer | mailto:andreas at xss.co.at
*x Software + Systeme | http://www.xss.co.at/
Karmarschgasse 51/2/20 | Tel: +43-1-6060114-0
A-1100 Vienna, Austria | Fax: +43-1-6060114-71
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAki4KoMACgkQxJmyeGcXPhG5zwCbB6mhRecTp7HDWX4aR5b8BIcZ
9b4AnAu4XerA3cbGxKmoi1NLZT/h40p5
=K3D5
-----END PGP SIGNATURE-----
More information about the kde-core-devel
mailing list