Skip to content

Commit 2f6c883

Browse files
committed
hv_sock: Fix incorrect readable byte reporting in hvs_stream_has_data()
* In f0c5827, the hvs_stream_has_data() function was modified to accurately return the number of readable bytes. * However, this caused an issue in the WSL2 environment where standard input redirection from Windows to Linux (e.g., echo hi | wsl -u root sh) silently failed, returning error code 1 without any warning. * This issue occurs when the payload of the current packet has been fully transmitted, but the descriptor has not yet been cleaned up in the recvmsg() path. * If the next packet is already waiting in the VMBus ring buffer, need_refill evaluated to false, incorrectly returning -EIO. * As a result, POLLERR was propagated to user space, leading to a premature termination of the stream and a broken pipe connection. * In 95e754d, this was modified to return 1 instead of -EIO to resolve the issue. * However, while returning an artificial positive byte count fixes the stdin pipe regression, it incorrectly reports the stream state to other hvsock users. * Since WSL2 interoperability uses blocking frame control messages on the hvsock channel, this false readability can manifest as an unexpected EOF or a protocol error. * Consequently, although rare, executable interoperability between WSL2 and the Windows host can be broken. * To address this, if the current descriptor is already consumed, we use the hv_pkt_iter_next() function to advance the iterator to the next packet, returning 0 if there are no more available packets. * Otherwise, it updates the cached receive state of the next packet and returns the length of the unread payload. * This approach prevents false errors caused by a stale recv_desc state while maintaining accurate reporting of unread bytes for the next packet. * This commit fixes f0c5827 and 95e754d. Bug: Nevuly/WSL2-Rolling-Kernel-Issue#42, Nevuly/WSL2-Rolling-Kernel-Issue#43 Fixes: f0c5827, 95e754d. Test: Build and type `echo echo hi | wsl -u root sh` in Windows CMD Signed-off-by: Yang Jeong Hun <onyxclover9931@gmail.com>
1 parent 7eb1598 commit 2f6c883

1 file changed

Lines changed: 9 additions & 12 deletions

File tree

net/vmw_vsock/hyperv_transport.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -703,18 +703,15 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk)
703703
switch (hvs_channel_readable_payload(hvs->chan)) {
704704
case 1:
705705
need_refill = !hvs->recv_desc;
706-
/*
707-
* recv_desc is not null, but recv_data_len is 0.
708-
* The current packet is drained but the ring buffer has more data.
709-
* return 1 to trigger EPOLLIN so recvmsg() can clean up the
710-
* current descriptor and fetch the next packet.
711-
*/
712-
if (!need_refill)
713-
return 1;
714-
715-
hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
716-
if (!hvs->recv_desc)
717-
return -ENOBUFS;
706+
if (!need_refill) {
707+
hvs->recv_desc = hv_pkt_iter_next(hvs->chan, hvs->recv_desc);
708+
if (!hvs->recv_desc)
709+
return 0;
710+
} else {
711+
hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
712+
if (!hvs->recv_desc)
713+
return -ENOBUFS;
714+
}
718715

719716
ret = hvs_update_recv_data(hvs);
720717
if (ret)

0 commit comments

Comments
 (0)