[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: branches/KDE/3.5/kdelibs/kinit
From: Dirk Mueller <mueller () kde ! org>
Date: 2008-04-25 23:57:23
Message-ID: 1209167843.317030.8990.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 801222 by mueller:
fix CVE-2008-1671: integer overflows and arbitrary
process kill vulnerability
M +22 -19 start_kdeinit.c
--- branches/KDE/3.5/kdelibs/kinit/start_kdeinit.c #801221:801222
@@ -37,9 +37,10 @@
not have this protection, kdeinit will after forking send the new
PID using the pipe and wait for a signal. This parent will reset the protection
and SIGUSR1 the process to continue.
+ returns 1 if pid is valid
*/
-static void set_protection( pid_t pid, int enable )
+static int set_protection( pid_t pid, int enable )
{
char buf[ 1024 ];
int procfile;
@@ -49,7 +50,7 @@
belongs to this user. */
struct stat st;
if( lstat( buf, &st ) < 0 || st.st_uid != getuid())
- return;
+ return 0;
}
procfile = open( buf, O_WRONLY );
if( procfile >= 0 ) {
@@ -59,6 +60,7 @@
write( procfile, "0", sizeof( "0" ));
close( procfile );
}
+ return 1;
}
int main(int argc, char **argv)
@@ -67,14 +69,14 @@
int new_argc;
const char** new_argv;
char helper_num[ 1024 ];
- int i;
+ unsigned i;
char** orig_environ = NULL;
char header[ 7 ];
if( pipe( pipes ) < 0 ) {
perror( "pipe()" );
return 1;
}
- if( argc > 1000 )
+ if( argc < 0 || argc > 1000 )
abort(); /* paranoid */
set_protection( getpid(), 1 );
switch( fork()) {
@@ -82,29 +84,30 @@
perror( "fork()" );
return 1;
default: /* parent, drop privileges and exec */
-#if defined (HAVE_SETEUID) && !defined (HAVE_SETEUID_FAKE)
- seteuid(getuid());
-#else
- setreuid(-1, getuid());
-#endif
- if (geteuid() != getuid()) {
+ if (setgid(getgid())) {
+ perror("setgid()");
+ return 1;
+ }
+ if (setuid(getuid()) || geteuid() != getuid()) {
perror("setuid()");
return 1;
}
close( pipes[ 0 ] );
/* read original environment passed by start_kdeinit_wrapper */
if( read( 0, header, 7 ) == 7 && strncmp( header, "environ", 7 ) == 0 ) {
- int count;
- if( read( 0, &count, sizeof( int )) == sizeof( int )) {
+ unsigned count;
+ if( read( 0, &count, sizeof( unsigned )) == sizeof( unsigned )
+ && count && count < (1<<16)) {
char** env = malloc(( count + 1 ) * sizeof( char* ));
int ok = 1;
for( i = 0;
i < count && ok;
++i ) {
- int len;
- if( read( 0, &len, sizeof( int )) == sizeof( int )) {
+ unsigned len;
+ if( read( 0, &len, sizeof( unsigned )) == sizeof( unsigned )
+ && len && len < (1<<12)) {
env[ i ] = malloc( len + 1 );
- if( read( 0, env[ i ], len ) == len ) {
+ if( (unsigned) read( 0, env[ i ], len ) == len ) {
env[ i ][ len ] = '\0';
} else {
ok = 0;
@@ -128,7 +131,7 @@
sprintf( helper_num, "%d", pipes[ 1 ] );
new_argv[ 2 ] = helper_num;
for( i = 1;
- i <= argc;
+ i <= (unsigned) argc;
++i )
new_argv[ i + 2 ] = argv[ i ];
if( orig_environ )
@@ -145,10 +148,10 @@
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 );
}
}
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic