]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
ipc: recv_cmd4 clobbers destination buffer on errors
authorEric Wong <e@80x24.org>
Sun, 24 Sep 2023 20:19:20 +0000 (20:19 +0000)
committerEric Wong <e@80x24.org>
Sun, 24 Sep 2023 23:14:20 +0000 (23:14 +0000)
Handling this should be done at the lowest levels possible;
so away from higher-level lei code.

lib/PublicInbox/CmdIPC4.pm
lib/PublicInbox/LEI.pm
lib/PublicInbox/LeiSelfSocket.pm
lib/PublicInbox/Spawn.pm
lib/PublicInbox/Syscall.pm
t/cmd_ipc.t

index 99890244456e8037d88923fd9d1fc327c5f5e5a7..4bc4c729d48314623adc3b863803e04aa49151b3 100644 (file)
@@ -31,7 +31,10 @@ no warnings 'once';
 *recv_cmd4 = sub ($$$) {
        my ($s, undef, $len) = @_; # $_[1] = destination buffer
        my $mh = Socket::MsgHdr->new(buflen => $len, controllen => 256);
-       my $r = Socket::MsgHdr::recvmsg($s, $mh, 0) // return (undef);
+       my $r = Socket::MsgHdr::recvmsg($s, $mh, 0) // do {
+               $_[1] = '';
+               return (undef);
+       };
        $_[1] = $mh->buf;
        return () if $r == 0;
        my (undef, undef, $data) = $mh->cmsghdr;
index 8b62def23f6a4abbe9c3b65b4b1db4ec22dcdc3a..1ead9bf6c6c0eec129fbcc0e08bbd12ab3aa2070 100644 (file)
@@ -1167,7 +1167,6 @@ sub event_step {
                if (scalar(@fds) == 1 && !defined($fds[0])) {
                        return if $! == EAGAIN;
                        die "recvmsg: $!" if $! != ECONNRESET;
-                       $buf = '';
                        @fds = (); # for open loop below:
                }
                for (@fds) { open my $rfh, '+<&=', $_ }
index 8436726650da9105ce3591017a822b71db85daae..b87452522f89cf1b563c00879c0ffb817ba9c0e7 100644 (file)
@@ -25,7 +25,6 @@ sub event_step {
        if (scalar(@fds) == 1 && !defined($fds[0])) {
                return if $!{EAGAIN};
                die "recvmsg: $!" unless $!{ECONNRESET};
-               $buf = '';
        } else { # just in case open so perl can auto-close them:
                for (@fds) { open my $fh, '+<&=', $_ };
        }
index ed698afc6c8e3d80b24674386a2e5df5707cc8ac..2b84e2d5fea4acced623871348b123a56269a4fe 100644 (file)
@@ -259,10 +259,12 @@ void recv_cmd4(PerlIO *s, SV *buf, STRLEN n)
        msg.msg_controllen = CMSG_SPACE(SEND_FD_SPACE);
 
        i = recvmsg(PerlIO_fileno(s), &msg, 0);
-       if (i < 0)
-               Inline_Stack_Push(&PL_sv_undef);
-       else
+       if (i >= 0) {
                SvCUR_set(buf, i);
+       } else {
+               Inline_Stack_Push(&PL_sv_undef);
+               SvCUR_set(buf, 0);
+       }
        if (i > 0 && cmsg.hdr.cmsg_level == SOL_SOCKET &&
                        cmsg.hdr.cmsg_type == SCM_RIGHTS) {
                size_t len = cmsg.hdr.cmsg_len;
index 0a0912fb2d06254e1ac4867f0fbca9bd5c2899ad..776fbe23dae6da6ca855aa6ec18de2f77f8da0bf 100644 (file)
@@ -444,7 +444,10 @@ no warnings 'once';
                        msg_controllen,
                        0); # msg_flags
        my $r = syscall($SYS_recvmsg, fileno($sock), $mh, 0);
-       return (undef) if $r < 0; # $! set
+       if ($r < 0) { # $! is set
+               $_[1] = '';
+               return (undef);
+       }
        substr($_[1], $r, length($_[1]), '');
        my @ret;
        if ($r > 0) {
index 461d2140a9b926540286075a41f9ebefaa25b259..7313d13b6cddfc61575b5f4bd8183031fa242dd1 100644 (file)
@@ -47,6 +47,7 @@ my $do_test = sub { SKIP: {
                $s2->blocking(0);
                @fds = $recv->($s2, $buf, length($src) + 1);
                ok($!{EAGAIN}, "EAGAIN set by ($desc)");
+               is($buf, '', "recv buffer emptied on EAGAIN ($desc)");
                is_deeply(\@fds, [ undef ], "EAGAIN $desc");
                $s2->blocking(1);