[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cobalt-users] [Cobalt] Security Advisory - Majordomo



Basically it fixes the way Majordomo opens file handles, instead of
using the default perl open command (which can open anything) it uses
sysopen.  I have attached a diff of changed files.

Jeff-



Jeff Lasman wrote:
> 
> Jeff,
> 
> Can you tell us what this package does?  Is it similar to smrsh?  I'd like
> to know how it implements fixes before I'd try it.
> 
> Thanks.
> 
> Jeff
> 
> At 08:45 PM 1/7/00  Jeff Bilicki wrote:
> 
> >Problem:
> >The currently installed version of majordomo that runs on all of
> >Cobalt's second and third generation products (Qube2, RaQ2, and
> >RaQ3) has a security issue that allows local users to obtain elevated
> >permissions.
>  > ...<balance snipped>...
> 
> --
> Jeff Lasman, nobaloney.net
> <jblists@xxxxxxxxxxxxx>
> <www.nobaloney.net>, <www.mailtraqna.com>, <www.email-lists.com>
> 
> _______________________________________________
> cobalt-users mailing list
> cobalt-users@xxxxxxxxxxxxxxx
> http://list.cobalt.com/mailman/listinfo/cobalt-users
--- /home/tmp/build/usr/local/majordomo/bounce-remind	Sun Jan  9 16:00:21 2000
+++ /usr/local/majordomo/bounce-remind	Sun Jan  9 16:05:14 2000
@@ -24,10 +24,18 @@
     shift(@ARGV);
     shift(@ARGV);
 }
-if (! -r $cf) {
-    die("$cf not readable; stopped");
-}
-require "$cf";
+
+# Open config file
+sysopen(CONF, $cf, O_RDONLY) or die("sysopen(CONF, \"$cf\", O_RDONLY): $!\nStopped");
+
+# Test to see if config is owned by effective UID.
+die("Configuration file \"$cf\" is not owned by effective UID.\nStopped") if ((stat CONF)[4] != $>);
+
+# Read it in or die
+die("Unable to eval \"$cf\": $@\nStopped") if (eval (join '',<CONF>), $@);
+
+# close it up
+close CONF;
 
 # Go to the home directory specified by the .cf file
 chdir("$homedir");
--- /home/tmp/build/usr/local/majordomo/config-test	Sun Jan  9 16:00:21 2000
+++ /usr/local/majordomo/config-test	Sun Jan  9 16:05:14 2000
@@ -119,11 +119,17 @@
 
 $cf = $ARGV[0] || $ENV{'MAJORDOMO_CF'};
 
-if (eval "require '$cf'") { 
-    &good("'require'd $cf okay.");    
-} else {
-    &bad("something's wrong with $cf: $@");
-}
+# Open config file
+sysopen(CONF, $cf, O_RDONLY) or die("sysopen(CONF, \"$cf\", O_RDONLY): $!\nStopped");
+
+# Test to see if config is owned by effective UID.
+die("Configuration file \"$cf\" is not owned by effective UID.\nStopped") if ((stat CONF)[4] != $>);
+
+# Read it in or die
+die("Unable to eval \"$cf\": $@\nStopped") if (eval (join '',<CONF>), $@);
+
+# close it up
+close CONF;
 
 foreach (@requires) {
     if (require $_) {
--- /home/tmp/build/usr/local/majordomo/digest	Sun Jan  9 16:00:21 2000
+++ /usr/local/majordomo/digest	Sun Jan  9 16:05:14 2000
@@ -315,7 +315,18 @@
 		# Read and execute the .cf file
 		$cf = $opt_c || $ENV{"MAJORDOMO_CF"} || 
 		    "/etc/majordomo.cf";
-		require "$cf";
+
+		# Open config file
+		sysopen(CONF, $cf, O_RDONLY) or die("sysopen(CONF, \"$cf\", O_RDONLY): $!\nStopped");
+
+		# Test to see if config is owned by effective UID.
+		die("Configuration file \"$cf\" is not owned by effective UID.\nStopped") if ((stat CONF)[4] != $>);
+
+		# Read it in or die
+		die("Unable to eval \"$cf\": $@\nStopped") if (eval (join '',<CONF>), $@);
+
+		# close it up
+		close CONF;
 
 		chdir($homedir);
 
--- /home/tmp/build/usr/local/majordomo/majordomo	Sun Jan  9 16:00:21 2000
+++ /usr/local/majordomo/majordomo	Sun Jan  9 16:05:14 2000
@@ -40,11 +40,18 @@
 	die "Unknown argument $ARGV[0]\n";
     }
 }
-if (! -r $cf) {
-    die("$cf not readable; stopped");
-}
 
-require "$cf";
+# Open config file
+sysopen(CONF, $cf, O_RDONLY) or die("sysopen(CONF, \"$cf\", O_RDONLY): $!\nStopped");
+
+# Test to see if config is owned by effective UID.
+die("Configuration file \"$cf\" is not owned by effective UID.\nStopped") if ((stat CONF)[4] != $>);
+
+# Read it in or die
+die("Unable to eval \"$cf\": $@\nStopped") if (eval (join '',<CONF>), $@);
+
+# close it up
+close CONF;
 
 # Go to the home directory specified by the .cf file
 chdir("$homedir") || die "chdir to $homedir failed, $!\n";
--- /home/tmp/build/usr/local/majordomo/request-answer	Sun Jan  9 16:00:22 2000
+++ /usr/local/majordomo/request-answer	Sun Jan  9 16:05:14 2000
@@ -20,10 +20,18 @@
     shift(@ARGV); 
     shift(@ARGV); 
 }
-if (! -r $cf) {
-    die("$cf not readable; stopped");
-}
-require "$cf";
+
+# Open config file
+sysopen(CONF, $cf, O_RDONLY) or die("sysopen(CONF, \"$cf\", O_RDONLY): $!\nStopped");
+
+# Test to see if config is owned by effective UID.
+die("Configuration file \"$cf\" is not owned by effective UID.\nStopped") if ((stat CONF)[4] != $>);
+
+# Read it in or die
+die("Unable to eval \"$cf\": $@\nStopped") if (eval (join '',<CONF>), $@);
+
+# close it up
+close CONF;
 
 chdir($homedir) || die("Can't chdir(\"$homedir\"): $!");
 unshift(@INC, $homedir);
--- /home/tmp/build/usr/local/majordomo/resend	Sun Jan  9 16:00:23 2000
+++ /usr/local/majordomo/resend	Sun Jan  9 16:05:14 2000
@@ -56,7 +56,7 @@
 if ($ARGV[0] =~ /^\@/) {
     $fn = shift(@ARGV);
     $fn =~ s/^@//;
-    open(AV, $fn) || die("open(AV, \"$fn\"): $!\nStopped");
+    sysopen(AV, $fn, O_RDONLY) || die("sysopen(AV, \"$fn\", O_RDONLY): $!\nStopped");
     undef($/);	# set input field separator
     $av = <AV>;	# read whole file into string
     close(AV);
@@ -84,11 +84,17 @@
 # Despite not having a place to send the remains of the body,
 # it would be nice to send a message to root or postmaster, at least...
 #
-if (! -r $cf) {
-    die("$cf not readable; stopped");
-}
+# Open config file
+sysopen(CONF, $cf, O_RDONLY) or die("sysopen(CONF, \"$cf\", O_RDONLY): $!\nStopped");
+
+# Test to see if config is owned by effective UID.
+die("Configuration file \"$cf\" is not owned by effective UID.\nStopped") if ((stat CONF)[4] != $>);
+
+# Read it in or die
+die("Unable to eval \"$cf\": $@\nStopped") if (eval (join '',<CONF>), $@);
 
-require "$cf";
+# close it up
+close CONF;
 
 chdir($homedir) || die("Can't chdir(\"$homedir\"): $!");