You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by he...@apache.org on 2021/05/16 18:21:39 UTC

svn commit: r1889937 - in /spamassassin/trunk: lib/Mail/SpamAssassin/Util.pm spamd/spamd.raw

Author: hege
Date: Sun May 16 18:21:39 2021
New Revision: 1889937

URL: http://svn.apache.org/viewvc?rev=1889937&view=rev
Log:
Try to clean up some of the setuid/setgid code

Modified:
    spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm
    spamassassin/trunk/spamd/spamd.raw

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm?rev=1889937&r1=1889936&r2=1889937&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm Sun May 16 18:21:39 2021
@@ -1798,10 +1798,10 @@ sub receive_date {
 sub get_user_groups {
   my $suid = shift;
   dbg("util: get_user_groups: uid is $suid\n");
-  my ( $user, undef, undef, $gid, undef ) = getpwuid($suid);
-  my $rgids="$gid ";
-  while ( my($name,undef,$gid,$members) = getgrent() ) {
-    if ( grep { $_ eq $user } split(/ /, $members) ) {
+  my ($user, $gid) = (getpwuid($suid))[0,3];
+  my $rgids = "$gid ";
+  while (my($name,$gid,$members) = (getgrent())[0,2,3]) {
+    if (grep { $_ eq $user } split(/ /, $members)) {
       $rgids .= "$gid ";
       dbg("util: get_user_groups: added $gid ($name) to group list which is now: $rgids\n");
     }
@@ -1823,14 +1823,22 @@ sub setuid_to_euid {
   defined $supgs or $supgs=$pgid;
   if ($( != $pgid) {
     # Gotta be root for any of this to work
-    $> = 0 ;
+    $> = 0;
+    if ($> != 0) { warn("util: seteuid to 0 failed: $!"); }
     dbg("util: changing real primary gid from $( to $pgid and supplemental groups to $supgs to match effective uid $touid");
-    POSIX::setgid($pgid);
-    dbg("util: POSIX::setgid($pgid) set errno to $!");  
-    $! = 0;
-    $( = $pgid;
-    $) = "$pgid $supgs";
-    dbg("util: assignment  \$) = $pgid $supgs set errno to $!");  
+    $! = 0; POSIX::setgid($pgid);
+    if ($!) { warn("util: POSIX::setgid $pgid failed: $!\n"); }
+    $! = 0; $( = $pgid;
+    if ($!) { warn("util: failed to set gid $pgid: $!\n"); }
+    $! = 0; $) = "$pgid $supgs";
+    if ($!) {
+      # could be perl 5.30 bug #134169, let's be safe
+      if (grep { $_ eq '0' } split(/ /, ${)})) {
+        die("util: failed to set effective gid $pgid $supgs: $!\n");
+      } else {
+        warn("util: failed to set effective gid $pgid $supgs: $!\n");
+      }
+    }
   }
   if ($< != $touid) {
     dbg("util: changing real uid from $< to match effective uid $touid");
@@ -1914,7 +1922,7 @@ sub helper_app_pipe_open_unix {
   eval {
     # go setuid...
     setuid_to_euid();
-    dbg("util: setuid: ruid=$< euid=$> rgid=$( egid=$) ");
+    dbg("util: setuid: ruid=$< euid=$> rgid=$( egid=$)");
 
     # now set up the fds.  due to some weirdness, we may have to ensure that
     # we *really* close the correct fd number, since some other code may have

Modified: spamassassin/trunk/spamd/spamd.raw
URL: http://svn.apache.org/viewvc/spamassassin/trunk/spamd/spamd.raw?rev=1889937&r1=1889936&r2=1889937&view=diff
==============================================================================
--- spamassassin/trunk/spamd/spamd.raw (original)
+++ spamassassin/trunk/spamd/spamd.raw Sun May 16 18:21:39 2021
@@ -1380,22 +1380,31 @@ sub spawn {
       # bug 3900: assignments to $> and $< problems with BSD perl bug
       # use the POSIX functions to hide the platform specific workarounds 
       dbg("spamd: Privilege de-escalation from user $< and groups $(\n");
-      $! = 0;
-      POSIX::setgid($ugid);  # set effective and real gid
-      dbg("spamd: setgid ERRNO is $!\n");
-      $( = $ugid;
-      $) = "$ugid ".(get_user_groups($uuid));  # set effective and real gid/grouplist another way because we lack initgroups in Perl
-      dbg("spamd: group assignment ERRNO is $!\n");
-      POSIX::setuid($uuid);  # set effective and real UID
-      dbg("spamd: setuid ERRNO is $!\n");
-      $< = $uuid; $> = $uuid;   # bug 5574
-      dbg("spamd: uid assignment ERRNO is $!\n");
-      dbg("spamd: real user is $< \neff user is $> \nreal groups are $( \neff groups are $) \n");
+      $! = 0; POSIX::setgid($ugid);  # set effective and real gid
+      if ($!) { warn("spamd: POSIX::setgid $ugid failed: $!\n"); }
+      $! = 0; $( = $ugid;
+      if ($!) { warn("spamd: failed to set gid $ugid: $!\n"); }
+      # set effective and real gid/grouplist another way because we lack initgroups in Perl
+      my $togids = "$ugid ".get_user_groups($uuid);
+      $! = 0; $) = $togids;
+      if ($!) {
+        # could be perl 5.30 bug #134169, let's be safe
+        if (grep { $_ eq '0' } split(/ /, ${)})) {
+          die("spamd: failed to set effective gid $togids: $!\n");
+        } else {
+          warn("spamd: failed to set effective gid $togids: $!\n");
+        }
+      }
+      $! = 0; POSIX::setuid($uuid);  # set effective and real UID
+      if ($!) { warn("spamd: POSIX::setuid $uuid failed: $!\n"); }
+      $! = 0; $< = $uuid; $> = $uuid;   # bug 5574
+      if ($!) { warn("spamd: setuid $uuid failed: $!\n"); }
+      dbg("spamd: now running as: ruid=$< euid=$> rgid=$( egid=$)");
 
       # keep the sanity check to catch problems like bug 3900 just in case
       if ( $> != $uuid and $> != ( $uuid - 2**32 ) ) {
         sleep(1); # prevent spamd fork flooding
-        die "spamd: setuid to uid $uuid failed (> = $>, < = $<), not started as root?\n";
+        die "spamd: setuid to uid $uuid failed (ruid=$<, euid=$>), not started as root?\n";
       }
     }