http://bugzilla.spamassassin.org/show_bug.cgi?id=3649





------- Additional Comments From [EMAIL PROTECTED]  2004-09-28 17:00 -------
Okay, after several failed attempts to attach the file (kept telling me no file 
was spcified for attachment), here is the diff -u output:

diff -u 
lib/Mail/SpamAssassin/Util.pm /usr/lib/perl5/site_perl/5.8.3/Mail/SpamAssassin/U
til.pm
=========================
--- lib/Mail/SpamAssassin/Util.pm       2004-09-13 16:34:05.000000000 -0700
+++ /usr/lib/perl5/site_perl/5.8.3/Mail/SpamAssassin/Util.pm    2004-09-28 
16:13:56.000000000 -0700
@@ -41,6 +41,7 @@
 use Time::Local;
 use Sys::Hostname (); # don't import hostname() into this namespace!
 use Fcntl;
+use POSIX (); # don't import anything unless we ask explicitly!
 
 ###########################################################################
 
@@ -1024,14 +1025,55 @@
   setuid_to_euid();
   dbg ("setuid: helper proc $$: ruid=$< euid=$>");
 
-  if ($stdinfile) {              # < $tmpfile
-    close STDIN;
-    open (STDIN, "<$stdinfile") or die "cannot open $stdinfile: $!";
-  }
+  # now set up the fds.  due to some wierdness, we may have to ensure that we
+  # *really* close the correct fd number, since some other code may have
+  # redirected the meaning of STDOUT/STDIN/STDERR it seems... (bug 3649). use
+  # POSIX::close() for that. it's safe to call close() and POSIX::close() on
+  # the same fd; the latter is a no-op in that case.
+
+  if (!$stdinfile) {              # < $tmpfile
+    # ensure we have *some* kind of fd 0.
+    $stdinfile = "/dev/null";
+  }
+
+  my $f = fileno(STDIN);
+  close STDIN;
+
+  # sanity: was that the *real* STDIN? if not, close that one too ;)
+  if ($f != 0) {
+    POSIX::close(0);
+  }
+  open STDIN, "<$stdinfile" or die "cannot open $stdinfile: $!";
+
+  # this should be impossible; if we just closed fd 0, UNIX
+  # fd behaviour dictates that the next fd opened (the new STDIN)
+  # will be the lowest unused fd number, which should be 0.
+  # so die with a useful error if this somehow isn't the case.
+  if (fileno(STDIN) != 0) {
+    die "setuid: oops: fileno(STDIN) [".fileno(STDIN)."] != 0";
+  }
+
+  # ensure STDOUT is open.  since we just created a pipe to ensure
+  # this, it has to be open to that pipe, and if it isn't, something's
+  # seriously screwy.
+  #if (fileno(STDOUT) != 1) {
+  #  die "setuid: oops: fileno(STDOUT) [".fileno(STDOUT)."] != 1";
+  #}
 
   if ($duperr2out) {             # 2>&1
+    my $f = fileno(STDERR);
     close STDERR;
+
+    # sanity: was that the *real* STDERR? if not, close that one too ;)
+    if ($f != 2) {
+      POSIX::close(2);
+    }
     open STDERR, ">&STDOUT" or die "dup STDOUT failed: $!";
+
+    # STDERR must be fd 2 to be useful to subprocesses! (bug 3649)
+    if (fileno(STDERR) != 2) {
+      die "setuid: oops: fileno(STDERR) [".fileno(STDERR)."] != 2";
+    }
   }
 
   exec @cmdline;
=========================

Let me know if you need anything else.

Bill



------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

Reply via email to