about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2021-01-22 20:01:19 +0000
committerEric Wong <e@80x24.org>2021-01-24 10:09:51 +0000
commitcea37260f3d63a4e497f0e5803d2a40c6f89dc0d (patch)
treefccee9d60a0c66c5b269c45996e3621defad6eea
parent6a0a324f2dd354c17ccc7a97604c5b1e17bea18e (diff)
downloadpublic-inbox-cea37260f3d63a4e497f0e5803d2a40c6f89dc0d.tar.gz
This prevents name conflicts leading to retries and slowdowns in
temporary file name generation.  No actual data corruption
resulted because all temporary files are opened with O_EXCL
anyways.

This may increase security for IMAP, NNTP, and HTTPS sessions
using TLS, but it's all public data anyways.
-rw-r--r--lib/PublicInbox/Daemon.pm3
-rw-r--r--lib/PublicInbox/IPC.pm6
-rw-r--r--lib/PublicInbox/Watch.pm6
-rw-r--r--lib/PublicInbox/Xapcmd.pm4
4 files changed, 17 insertions, 2 deletions
diff --git a/lib/PublicInbox/Daemon.pm b/lib/PublicInbox/Daemon.pm
index f5543c85..b5f97d81 100644
--- a/lib/PublicInbox/Daemon.pm
+++ b/lib/PublicInbox/Daemon.pm
@@ -533,10 +533,13 @@ EOF
                 if ($n <= $want) {
                         PublicInbox::DS::block_signals() if !$sigfd;
                         for my $i ($n..$want) {
+                                my $seed = rand(0xffffffff);
                                 my $pid = fork;
                                 if (!defined $pid) {
                                         warn "failed to fork worker[$i]: $!\n";
                                 } elsif ($pid == 0) {
+                                        srand($seed);
+                                        eval { Net::SSLeay::randomize() };
                                         $set_user->() if $set_user;
                                         return $p0; # run normal work code
                                 } else {
diff --git a/lib/PublicInbox/IPC.pm b/lib/PublicInbox/IPC.pm
index dbb87e4e..6efaff38 100644
--- a/lib/PublicInbox/IPC.pm
+++ b/lib/PublicInbox/IPC.pm
@@ -105,8 +105,10 @@ sub ipc_worker_spawn {
         pipe(my ($r_res, $w_res)) or die "pipe: $!";
         my $sigset = $oldset // PublicInbox::DS::block_signals();
         $self->ipc_atfork_prepare;
-        defined(my $pid = fork) or die "fork: $!";
+        my $seed = rand(0xffffffff);
+        my $pid = fork // die "fork: $!";
         if ($pid == 0) {
+                srand($seed);
                 eval { PublicInbox::DS->Reset };
                 delete @$self{qw(-wq_s1 -wq_workers -wq_ppid)};
                 $w_req = $r_res = undef;
@@ -286,8 +288,10 @@ sub wq_do { # always async
 
 sub _wq_worker_start ($$) {
         my ($self, $oldset) = @_;
+        my $seed = rand(0xffffffff);
         my $pid = fork // die "fork: $!";
         if ($pid == 0) {
+                srand($seed);
                 eval { PublicInbox::DS->Reset };
                 delete @$self{qw(-wq_s1 -wq_workers -wq_ppid)};
                 $SIG{$_} = 'IGNORE' for (qw(PIPE TTOU TTIN));
diff --git a/lib/PublicInbox/Watch.pm b/lib/PublicInbox/Watch.pm
index 9a729140..1de5018d 100644
--- a/lib/PublicInbox/Watch.pm
+++ b/lib/PublicInbox/Watch.pm
@@ -625,8 +625,11 @@ sub imap_idle_fork ($$) {
         my ($self, $url_intvl) = @_;
         my ($url, $intvl) = @$url_intvl;
         pipe(my ($r, $w)) or die "pipe: $!";
+        my $seed = rand(0xffffffff);
         defined(my $pid = fork) or die "fork: $!";
         if ($pid == 0) {
+                srand($seed);
+                eval { Net::SSLeay::randomize() };
                 close $r;
                 watch_atfork_child($self);
                 watch_imap_idle_1($self, $url, $intvl);
@@ -704,8 +707,11 @@ sub poll_fetch_fork ($) { # DS::add_timer callback
         return if $self->{quit};
         pipe(my ($r, $w)) or die "pipe: $!";
         my $oldset = watch_atfork_parent($self);
+        my $seed = rand(0xffffffff);
         my $pid = fork;
         if (defined($pid) && $pid == 0) {
+                srand($seed);
+                eval { Net::SSLeay::randomize() };
                 close $r;
                 watch_atfork_child($self);
                 if ($urls->[0] =~ m!\Aimaps?://!i) {
diff --git a/lib/PublicInbox/Xapcmd.pm b/lib/PublicInbox/Xapcmd.pm
index 8de516ef..269aa99a 100644
--- a/lib/PublicInbox/Xapcmd.pm
+++ b/lib/PublicInbox/Xapcmd.pm
@@ -89,8 +89,10 @@ sub commit_changes ($$$$) {
 
 sub cb_spawn {
         my ($cb, $args, $opt) = @_; # $cb = cpdb() or compact()
-        defined(my $pid = fork) or die "fork: $!";
+        my $seed = rand(0xffffffff);
+        my $pid = fork // die "fork: $!";
         return $pid if $pid > 0;
+        srand($seed);
         $cb->($args, $opt);
         POSIX::_exit(0);
 }