$OpenBSD: patch-spamd_spamd_raw,v 1.9 2018/02/23 17:07:35 giovanni Exp $
Index: spamd/spamd.raw
--- spamd/spamd.raw.orig
+++ spamd/spamd.raw
@@ -246,7 +246,8 @@ use Mail::SpamAssassin::SubProcBackChannel;
 use Mail::SpamAssassin::SpamdForkScaling qw(:pfstates);
 use Mail::SpamAssassin::Logger qw(:DEFAULT log_message);
 use Mail::SpamAssassin::Util qw(untaint_var untaint_file_path
-                                exit_status_str am_running_on_windows);
+                                exit_status_str am_running_on_windows
+                                get_user_groups);
 use Mail::SpamAssassin::Timeout;
 
 use Getopt::Long;
@@ -1071,7 +1072,6 @@ sub server_sock_setup_inet {
     $sockopt{V6Only} = 1  if $io_socket_module_name eq 'IO::Socket::IP'
                              && IO::Socket::IP->VERSION >= 0.09;
     %sockopt = (%sockopt, (
-      SSL_version     => $sslversion,
       SSL_verify_mode => 0x00,
       SSL_key_file    => $opt{'server-key'},
       SSL_cert_file   => $opt{'server-cert'},
@@ -1092,7 +1092,8 @@ sub server_sock_setup_inet {
     if (!$server_inet) {
       $diag = sprintf("could not create %s socket on [%s]:%s: %s",
                       $ssl ? 'IO::Socket::SSL' : $io_socket_module_name,
-                      $adr, $port, $!);
+                      $adr, $port, $ssl && $IO::Socket::SSL::SSL_ERROR ?
+                      "$!,$IO::Socket::SSL::SSL_ERROR" : $!);
       push(@diag_fail, $diag);
     } else {
       $diag = sprintf("created %s socket on [%s]:%s",
@@ -1369,10 +1370,20 @@ sub spawn {
       # bug 5518: assignments to $) and $( don't always work on all platforms
       # 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");
 
+
       # keep the sanity check to catch problems like bug 3900 just in case
       if ( $> != $uuid and $> != ( $uuid - 2**32 ) ) {
         die "spamd: setuid to uid $uuid failed (> = $>, < = $<)\n";
@@ -1521,7 +1532,7 @@ sub accept_from_any_server_socket {
     } # end multiple sockets case
 
     if ($selected_socket_info) {
-      my $socket = $selected_socket_info->{socket};
+      $socket = $selected_socket_info->{socket};
       $socket or die "no socket???, impossible";
       dbg("spamd: accept() on fd %d", $selected_socket_info->{fd});
       $client = $socket->accept;
@@ -1726,7 +1737,7 @@ sub handle_setuid_to_user {
     my ($name, $pwd, $uid, $gid, $quota, $comment, $gcos, $dir, $etc) =
         getpwnam('nobody');
   
-    $) = "$gid $gid";                   # eGID
+    $) = (get_user_groups($uid));       # eGID
     $> = $uid;                          # eUID
     if (!defined($uid) || ($> != $uid and $> != ($uid - 2**32))) {
       die("spamd: setuid to nobody failed");
@@ -2488,7 +2499,7 @@ sub handle_user_setuid_basic {
   }
 
   if ($setuid_to_user) {
-    $) = "$gid $gid";                 # change eGID
+    $) = (get_user_groups($uid));     # change eGID
     $> = $uid;                        # change eUID
     if ( !defined($uid) || ( $> != $uid and $> != ( $uid - 2**32 ) ) ) {
       # make it fatal to avoid security breaches
@@ -2710,7 +2721,7 @@ sub handle_user_setuid_with_sql {
   }
 
   if ($setuid_to_user) {
-    $) = "$gid $gid";                 # change eGID
+    $) = (get_user_groups($uid));     # change eGID
     $> = $uid;                        # change eUID
     if (!defined($uid) || ($> != $uid and $> != ($uid - 2**32))) {
       # make it fatal to avoid security breaches
@@ -2755,7 +2766,7 @@ sub handle_user_setuid_with_ldap {
   }
 
   if ($setuid_to_user) {
-    $) = "$gid $gid";    # change eGID
+    $) = (get_user_groups($uid));    # change eGID
     $> = $uid;           # change eUID
     if (!defined($uid) || ($> != $uid and $> != ($uid - 2**32))) {
       # make it fatal to avoid security breaches
