From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.2 required=3.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id EBC1F1F567 for ; Sun, 24 Sep 2023 20:19:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1695586763; bh=xYaMhL/8BqlsYMAalEJyislB+r3yxkTmq8+kORURMwQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=pVQ4B8ycsyXnGoubKc+i2B3C1M76Wzz2ztmpEIGY/6NndzjGS5/3g8k8CV1Dhx97G 0tkpf/v5fQ0dC+sOHq6P5dZPxjSIi9k5e8VN4NDp6GrXB5XITDySJAwRY4d5ieQHdR mldDMxv3y84WHuHpb2mC04gY4Jndj1MuJmpk1uSE= From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 4/6] ipc: recv_cmd4 clobbers destination buffer on errors Date: Sun, 24 Sep 2023 20:19:20 +0000 Message-ID: <20230924201922.4031002-5-e@80x24.org> In-Reply-To: <20230924201922.4031002-1-e@80x24.org> References: <20230924201922.4031002-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Handling this should be done at the lowest levels possible; so away from higher-level lei code. --- lib/PublicInbox/CmdIPC4.pm | 5 ++++- lib/PublicInbox/LEI.pm | 1 - lib/PublicInbox/LeiSelfSocket.pm | 1 - lib/PublicInbox/Spawn.pm | 8 +++++--- lib/PublicInbox/Syscall.pm | 5 ++++- t/cmd_ipc.t | 1 + 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/PublicInbox/CmdIPC4.pm b/lib/PublicInbox/CmdIPC4.pm index 99890244..4bc4c729 100644 --- a/lib/PublicInbox/CmdIPC4.pm +++ b/lib/PublicInbox/CmdIPC4.pm @@ -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; diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index 8b62def2..1ead9bf6 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -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, '+<&=', $_ } diff --git a/lib/PublicInbox/LeiSelfSocket.pm b/lib/PublicInbox/LeiSelfSocket.pm index 84367266..b8745252 100644 --- a/lib/PublicInbox/LeiSelfSocket.pm +++ b/lib/PublicInbox/LeiSelfSocket.pm @@ -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, '+<&=', $_ }; } diff --git a/lib/PublicInbox/Spawn.pm b/lib/PublicInbox/Spawn.pm index ed698afc..2b84e2d5 100644 --- a/lib/PublicInbox/Spawn.pm +++ b/lib/PublicInbox/Spawn.pm @@ -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; diff --git a/lib/PublicInbox/Syscall.pm b/lib/PublicInbox/Syscall.pm index 0a0912fb..776fbe23 100644 --- a/lib/PublicInbox/Syscall.pm +++ b/lib/PublicInbox/Syscall.pm @@ -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) { diff --git a/t/cmd_ipc.t b/t/cmd_ipc.t index 461d2140..7313d13b 100644 --- a/t/cmd_ipc.t +++ b/t/cmd_ipc.t @@ -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);