[vhffs-dev] [1589] fixed process check, now checking after setuid()/setguid() and after chroot; removed additionnals groups through setgroups(); fixed reading of data sent just at the end of the child process ( wait for the pipe to be closed)

[ Thread Index | Date Index | More vhffs.org/vhffs-dev Archives ]


Revision: 1589
Author:   gradator
Date:     2010-04-08 22:45:57 +0200 (Thu, 08 Apr 2010)
Log Message:
-----------
fixed process check, now checking after setuid()/setguid() and after chroot; removed additionnals groups through setgroups(); fixed reading of data sent just at the end of the child process (wait for the pipe to be closed)

Modified Paths:
--------------
    trunk/vhffs-robots/src/cron_scheduler.pl

Modified: trunk/vhffs-robots/src/cron_scheduler.pl
===================================================================
--- trunk/vhffs-robots/src/cron_scheduler.pl	2010-04-07 20:42:44 UTC (rev 1588)
+++ trunk/vhffs-robots/src/cron_scheduler.pl	2010-04-08 20:45:57 UTC (rev 1589)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!%PERL%
 # Copyright (c) vhffs project and its contributors
 # All rights reserved.
 #
@@ -36,6 +36,7 @@
 use IO::Handle;
 use IO::Select;
 use BSD::Resource;
+use English;
 #use Data::Dumper;
 
 use constant
@@ -43,6 +44,8 @@
 	STATUS_CREATED => 0,
 	STATUS_RUNNING => 1,
 	STATUS_KILLED => 2,
+
+	FAIL_TO_RUN_PROCESS_EXIT_CODE => 136,
 };
 
 use lib '%VHFFS_LIB_DIR%';
@@ -97,38 +100,44 @@
 
 	foreach ( keys %jobs )  {
 		my $job = $jobs{$_};
+
 		if( $job->{'status'} == STATUS_CREATED )  {
 			run_job( $job ) if( time() > $job->{'runat'} );
+			next;
 		}
-		else {
-			if ( $job->{'status'} == STATUS_RUNNING )  {
-				if( defined $maxexectime  &&  $maxexectime > 0  &&  time() - $job->{'startedat'} > $maxexectime ) {
-					kill 9, $job->{'pid'};
-					$job->{'status'} = STATUS_KILLED;
-				}
+
+		if ( $job->{'status'} == STATUS_RUNNING )  {
+			if( defined $maxexectime  &&  $maxexectime > 0  &&  time() - $job->{'startedat'} > $maxexectime ) {
+				kill 9, $job->{'pid'};
+				$job->{'status'} = STATUS_KILLED;
+				next;
 			}
+		}
 
-			my $pid = waitpid( $job->{'pid'}, POSIX::WNOHANG );
-			my $returnvalue = $? >> 8;
-			if ( $pid == $job->{'pid'} ) {
-				my $cron = $job->{'cron'};
+		next if defined $job->{'pipe'};
+
+		my $pid = waitpid( $job->{'pid'}, POSIX::WNOHANG );
+		my $returnvalue = $? >> 8;
+		next if $pid != $job->{'pid'};
+
+		my $cron = $job->{'cron'};
+		
+		$job->{'output'} .= "\n------KILLED------\n" if( $job->{'status'} == STATUS_KILLED );
 			
-				$job->{'output'} .= "\n------KILLED------\n" if( $job->{'status'} == STATUS_KILLED );
+		if( defined $job->{'output'}  &&  $job->{'output'} ne '' )  {
 			
-				if( defined $job->{'output'}  &&  $job->{'output'} ne '' )  {
-			
-					my $body = 'Exit value: '. $returnvalue."\n\n";
-					$body .= 'WARNING: This process was killed because it were still running after more than '.$maxexectime.' seconds'."\n\n" if( $job->{'status'} == STATUS_KILLED );
-					$body .= "\n--- Environment ---\n\n".$job->{'env'}."\n\n--- Stdout and stderr output ---\n\n".$job->{'output'}."\n";
-					sendmail_cron( $cron , $body );
-				}
-			
-				$cron->quick_set_nextrundate( time() + $cron->get_interval );
-				$cron->quick_set_lastrun( $job->{'createdat'} , $returnvalue );
-				$cron->quick_dec_running();
-				destroy_job( $job );
-			}
+			my $body = 'Exit value: '. $returnvalue."\n\n";
+			$body .= 'WARNING: This process was killed because it were still running after more than '.$maxexectime.' seconds'."\n\n" if( $job->{'status'} == STATUS_KILLED );
+			$body .= "\n--- Environment ---\n\n".$job->{'env'}."\n\n--- Stdout and stderr output ---\n\n".$job->{'output'}."\n";
+			sendmail_cron( $cron , $body );
 		}
+
+		my $nextinterval = $cron->get_interval;
+		$nextinterval = 600 if $returnvalue == FAIL_TO_RUN_PROCESS_EXIT_CODE;
+		$cron->quick_set_nextrundate( time() + $nextinterval );
+		$cron->quick_set_lastrun( $job->{'createdat'} , $returnvalue );
+		$cron->quick_dec_running();
+		destroy_job( $job );
 	}
 
 	my ($rh_set) = IO::Select->select($read_set, undef, undef, 1);
@@ -150,7 +159,10 @@
 			}
 		}
 		else {
+			delete $fd2jobs{ $rh->fileno };
 			$read_set->remove( $rh );
+			close( $rh );
+			$job->{'pipe'} = undef;
 		}
 	}
 
@@ -165,41 +177,8 @@
 {
 	my $cron = shift;
 	my $cron_id = $cron->get_cron_id;
-	my $fullpath = $cron->get_cronpath;
-	$fullpath = $chroot.'/'.$fullpath if defined $chroot;
 
-	unless( -f $fullpath && -x $fullpath )  {
-		my $body = "CRITICAL: The path is neither a regular file nor an executable\n";
-		sendmail_cron( $cron , $body );
-		$cron->quick_set_nextrundate( time() + 600 );
-		return undef;
-	}
-
-	my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($fullpath);
-
-	unless( $gid == $cron->get_owner_gid )  {
-		my $body = "CRITICAL: GID of file don't match the owner GID of this object in the VHFFS database\n";
-		sendmail_cron( $cron , $body );
-		$cron->quick_set_nextrundate( time() + 600 );
-		return undef;
-	}
-
-	unless( $uid == $cron->get_owner_uid )  {
-		my $body = "CRITICAL: UID of file don't match the owner UID of this object in the VHFFS database\n";
-		sendmail_cron( $cron , $body );
-		$cron->quick_set_nextrundate( time() + 600 );
-		return undef;
-	}
-
-	if( $mode & S_IWOTH )  {
-		my $body = "CRITICAL: File is writeable by others, I am not going to execute that\n";
-		sendmail_cron( $cron , $body );
-		$cron->quick_set_nextrundate( time() + 600 );
-		return undef;
-	}
-
 	$jobs{$cron_id}{'cron'} = $cron;
-	$jobs{$cron_id}{'fullpath'} = $fullpath;
 	$jobs{$cron_id}{'pid'} = undef;
 	$jobs{$cron_id}{'pipe'} = undef;
 	$jobs{$cron_id}{'output'} = undef;
@@ -244,6 +223,7 @@
 	
 	unless( pipe( $par, $son ) )  {
 		print "pipe() failed\n";
+		destroy_job( $job );
 		return 1;
 	}
 
@@ -252,6 +232,7 @@
 		print "fork() failed\n";
 		close $par;
 		close $son;
+		destroy_job( $job );
 		return 1;
 	}
 
@@ -288,8 +269,6 @@
 		}
 		print $son "\n";
 
-		chroot $chroot if defined $chroot;
-
 		foreach my $resource ( keys %{$limits} )  {
 			my ( $soft , $hard ) = ( $limits->{$resource} =~ /^\s*([\d\w]+)\s+([\d\w]+)\s*$/ );
 
@@ -301,11 +280,38 @@
 		}
 
 		POSIX::nice $nice;
-		POSIX::setgid $cron->get_owner_gid;
-		POSIX::setuid $cron->get_owner_uid;
-		return 1 unless( getuid() == $cron->get_owner_uid && getgid() == $cron->get_owner_gid );
 
-		exec $cron->get_cronpath;
+		chroot $chroot if defined $chroot;
+
+		$GID = $EGID = $cron->get_owner_gid.' '.$cron->get_owner_gid;
+		$UID = $EUID = $cron->get_owner_uid;
+		return 1 unless( POSIX::getuid() == $cron->get_owner_uid && POSIX::getgid() == $cron->get_owner_gid );
+
+		my $cronpath = $cron->get_cronpath;
+
+		unless( -f $cronpath && -x $cronpath )  {
+			print $son "CRITICAL: The path is neither a regular file nor an executable\n";
+			_exit(FAIL_TO_RUN_PROCESS_EXIT_CODE);
+		}
+
+		my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($cronpath);
+
+		unless( $gid == $cron->get_owner_gid )  {
+			print $son "CRITICAL: GID of file don't match the owner GID of this object in the VHFFS database\n";
+			_exit(FAIL_TO_RUN_PROCESS_EXIT_CODE);
+		}
+
+		unless( $uid == $cron->get_owner_uid )  {
+			print $son "CRITICAL: UID of file don't match the owner UID of this object in the VHFFS database\n";
+			_exit(FAIL_TO_RUN_PROCESS_EXIT_CODE);
+		}
+
+		if( $mode & S_IWOTH )  {
+			print $son "CRITICAL: File is writeable by others, I am not going to execute that\n";
+			exit(FAIL_TO_RUN_PROCESS_EXIT_CODE);
+		}		
+
+		exec $cron->get_cronpath;		
 		exit 1;
 	}
 }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/