From nobody Mon Feb 9 05:19:51 2026 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 449482EA743; Tue, 13 Jan 2026 15:09:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768316963; cv=none; b=PqwhyzZ0fGxFlE6SbVWNK6xfjSiJ+WpwFFDy/aEoY7/baI5/EYD7D+k6dCjIfG3tJuVgxxaLWJ1GJbeNOV65dO7hf97+sGHCUioWYrt7IgbuDBaPrMOH22+pZADGKx5Mf54su7wA3nXnBRtxXfME/Ya4/piXZzP/ZnyB121tJhQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768316963; c=relaxed/simple; bh=wU8qS8cqfDjx7nAp5iG/hVamv8f7I+sKdRiCrczLjL0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=J9wRPZIJEczdZAofQyL0E+NP09m+DmnX0p/Nn7ym9ymv26PqadKAsgdAxXGoCuz+vqgHUP1lqbrjd0oWkJjA55ifrJ4YOxoJfWIGmt1JnrM8az7rEjIO96tpgTR/y4bWTeej4UUBUfdK3JE6uUC4U53XKIj9mDDcJWDUF/KDkcE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rbox.co; spf=pass smtp.mailfrom=rbox.co; dkim=pass (2048-bit key) header.d=rbox.co header.i=@rbox.co header.b=OYq8tdRm; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rbox.co Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rbox.co Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rbox.co header.i=@rbox.co header.b="OYq8tdRm" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vfg1C-00GFuz-DB; Tue, 13 Jan 2026 16:09:14 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=rbox.co; s=selector2; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From; bh=htTm+t/o8GPw74fFM1N90567gOu8ehL2M/ELxAg+cbc=; b=OYq8tdRmn8Yk0Kz1I8PsYAFKSH sNvHLHGL3F5p1BjBsrz+0aNP/HpiIq16D41Npx1ZedHVN8iZxyAqqhssm/MZsUTpPwM4SoJvipAsg 2lgMzWsGFAvhn3uWNYURpiWgRobG2tbgZbXSi7YbvTBJtuYyamV2PppzSknoo9P1jC2vetTVLglWv 6TmWn/o6ZELUJGJQMHFnmXaViyUfoG0C5oC6tgE4w62AdQrxhSuf8Kq5a3MS2B11R97TmSP5Z8Egl t8H63bWhJBL+H2h3TV9k0ZGnAh7kF12kC2sFVPTg5STSPwULjgtAUAhDQ5dlLCkWGUfEldfoNSN9W O3wzeYlg==; Received: from [10.9.9.73] (helo=submission02.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vfg1B-0007w3-TZ; Tue, 13 Jan 2026 16:09:14 +0100 Received: by submission02.runbox with esmtpsa [Authenticated ID (604044)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vfg0v-00DMTf-6F; Tue, 13 Jan 2026 16:08:57 +0100 From: Michal Luczaj Date: Tue, 13 Jan 2026 16:08:18 +0100 Subject: [PATCH net v2 1/2] vsock/virtio: Coalesce only linear skb Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260113-vsock-recv-coalescence-v2-1-552b17837cf4@rbox.co> References: <20260113-vsock-recv-coalescence-v2-0-552b17837cf4@rbox.co> In-Reply-To: <20260113-vsock-recv-coalescence-v2-0-552b17837cf4@rbox.co> To: "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , =?utf-8?q?Eugenio_P=C3=A9rez?= , Stefan Hajnoczi , Stefano Garzarella , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Arseniy Krasnov Cc: kvm@vger.kernel.org, virtualization@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Michal Luczaj X-Mailer: b4 0.14.3 vsock/virtio common tries to coalesce buffers in rx queue: if a linear skb (with a spare tail room) is followed by a small skb (length limited by GOOD_COPY_LEN =3D 128), an attempt is made to join them. Since the introduction of MSG_ZEROCOPY support, assumption that a small skb will always be linear is incorrect. In the zerocopy case, data is lost and the linear skb is appended with uninitialized kernel memory. Of all 3 supported virtio-based transports, only loopback-transport is affected. G2H virtio-transport rx queue operates on explicitly linear skbs; see virtio_vsock_alloc_linear_skb() in virtio_vsock_rx_fill(). H2G vhost-transport may allocate non-linear skbs, but only for sizes that are not considered for coalescence; see PAGE_ALLOC_COSTLY_ORDER in virtio_vsock_alloc_skb(). Ensure only linear skbs are coalesced. Note that skb_tailroom(last_skb) > 0 guarantees last_skb is linear. Fixes: 581512a6dc93 ("vsock/virtio: MSG_ZEROCOPY flag support") Signed-off-by: Michal Luczaj Reviewed-by: Stefano Garzarella --- net/vmw_vsock/virtio_transport_common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio= _transport_common.c index dcc8a1d5851e..26b979ad71f0 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -1359,9 +1359,11 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk, =20 /* Try to copy small packets into the buffer of last packet queued, * to avoid wasting memory queueing the entire buffer with a small - * payload. + * payload. Skip non-linear (e.g. zerocopy) skbs; these carry payload + * in skb_shinfo. */ - if (len <=3D GOOD_COPY_LEN && !skb_queue_empty(&vvs->rx_queue)) { + if (len <=3D GOOD_COPY_LEN && !skb_queue_empty(&vvs->rx_queue) && + !skb_is_nonlinear(skb)) { struct virtio_vsock_hdr *last_hdr; struct sk_buff *last_skb; =20 --=20 2.52.0 From nobody Mon Feb 9 05:19:52 2026 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A4143904D1; Tue, 13 Jan 2026 15:09:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768316972; cv=none; b=MDk62ZBkwpvYev8xGmeV0tJaQcfitNID8H5Rx/rvrRZaG1MYn+YpJzaTO4lX9lVt7md4kGexTLey5BoURq9Ix1cPqDFPcMAMWO4OnaFk/GRdUhyEUn3vbDwTnmIxu0ba2uL3iuBda0ZazGcg6EtzfBOjzVK3LdU76AEwVlxZcEM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768316972; c=relaxed/simple; bh=+m/zcz9m5qjJUbvy4oHymY9PyGgul7PKAKQGzkSYjno=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=px5NkkqzW34UaDJuUxkn1S6+79mVqFru31RrG47jKyRUtL4kGjJR9RUdcevvZeroPARqYC0QtiYNIsSXFLRFJe7oZ+RNtZmkWEdfU+g07fpvAvizjSzQvwx7OMlYBsEo+e/RSvPqaSxyiI1qt2kyO5XMSY9s9ig0x6QoJ5611s0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rbox.co; spf=pass smtp.mailfrom=rbox.co; dkim=pass (2048-bit key) header.d=rbox.co header.i=@rbox.co header.b=WhE7lXar; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rbox.co Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rbox.co Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rbox.co header.i=@rbox.co header.b="WhE7lXar" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1vfg1B-00GIga-TJ; Tue, 13 Jan 2026 16:09:13 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=rbox.co; s=selector2; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From; bh=cY/xVqDotsaOhRcTT+mmKBIUBa7/ehWTCbrX7fejO/o=; b=WhE7lXarkujclW4JMyz1blCVA7 U096LEiJIJDuu/DxkbEZRe4dPlZhFZUS/w0BGt5NlnxVKofYJLWIqA5eN5JJts7VgwFayvrxCsIiH 9d48SDNcUmMCxL8kjc3m35dMMEGwzzbCxDclVg4NJtR2OcCuGgpEuMlf4tUvNbX8OCeJ35Pz+LZgT BMvCP0NjBEf/aT1neBJfj64klly806QmRCwLZR/rmByehsEprSstiTRRhMcOjGPN60L12UJx17kbp boduUz6fsZrhNoTgyHQY1ZBiiOQ2vioD6c6p1i+iAORRVtOZFcVB4peZ/xqdW0rDgZjr1kn0g860g uRXPoUww==; Received: from [10.9.9.73] (helo=submission02.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1vfg1A-0007vx-OB; Tue, 13 Jan 2026 16:09:12 +0100 Received: by submission02.runbox with esmtpsa [Authenticated ID (604044)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1vfg0w-00DMTf-1M; Tue, 13 Jan 2026 16:08:58 +0100 From: Michal Luczaj Date: Tue, 13 Jan 2026 16:08:19 +0100 Subject: [PATCH net v2 2/2] vsock/test: Add test for a linear and non-linear skb getting coalesced Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260113-vsock-recv-coalescence-v2-2-552b17837cf4@rbox.co> References: <20260113-vsock-recv-coalescence-v2-0-552b17837cf4@rbox.co> In-Reply-To: <20260113-vsock-recv-coalescence-v2-0-552b17837cf4@rbox.co> To: "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , =?utf-8?q?Eugenio_P=C3=A9rez?= , Stefan Hajnoczi , Stefano Garzarella , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Arseniy Krasnov Cc: kvm@vger.kernel.org, virtualization@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Michal Luczaj X-Mailer: b4 0.14.3 Loopback transport can mangle data in rx queue when a linear skb is followed by a small MSG_ZEROCOPY packet. To exercise the logic, send out two packets: a weirdly sized one (to ensure some spare tail room in the skb) and a zerocopy one that's small enough to fit in the spare room of its predecessor. Then, wait for both to land in the rx queue, and check the data received. Faulty packets merger manifests itself by corrupting payload of the later packet. Signed-off-by: Michal Luczaj Reviewed-by: Stefano Garzarella --- tools/testing/vsock/vsock_test.c | 5 +++ tools/testing/vsock/vsock_test_zerocopy.c | 74 +++++++++++++++++++++++++++= ++++ tools/testing/vsock/vsock_test_zerocopy.h | 3 ++ 3 files changed, 82 insertions(+) diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_t= est.c index bbe3723babdc..27e39354499a 100644 --- a/tools/testing/vsock/vsock_test.c +++ b/tools/testing/vsock/vsock_test.c @@ -2403,6 +2403,11 @@ static struct test_case test_cases[] =3D { .run_client =3D test_stream_accepted_setsockopt_client, .run_server =3D test_stream_accepted_setsockopt_server, }, + { + .name =3D "SOCK_STREAM virtio MSG_ZEROCOPY coalescence corruption", + .run_client =3D test_stream_msgzcopy_mangle_client, + .run_server =3D test_stream_msgzcopy_mangle_server, + }, {}, }; =20 diff --git a/tools/testing/vsock/vsock_test_zerocopy.c b/tools/testing/vsoc= k/vsock_test_zerocopy.c index 9d9a6cb9614a..a31ddfc1cd0c 100644 --- a/tools/testing/vsock/vsock_test_zerocopy.c +++ b/tools/testing/vsock/vsock_test_zerocopy.c @@ -9,14 +9,18 @@ #include #include #include +#include #include #include #include #include #include +#include +#include #include =20 #include "control.h" +#include "timeout.h" #include "vsock_test_zerocopy.h" #include "msg_zerocopy_common.h" =20 @@ -356,3 +360,73 @@ void test_stream_msgzcopy_empty_errq_server(const stru= ct test_opts *opts) control_expectln("DONE"); close(fd); } + +#define GOOD_COPY_LEN 128 /* net/vmw_vsock/virtio_transport_common.c */ + +void test_stream_msgzcopy_mangle_client(const struct test_opts *opts) +{ + char sbuf1[PAGE_SIZE + 1], sbuf2[GOOD_COPY_LEN]; + unsigned long hash; + struct pollfd fds; + int fd, i; + + fd =3D vsock_stream_connect(opts->peer_cid, opts->peer_port); + if (fd < 0) { + perror("connect"); + exit(EXIT_FAILURE); + } + + enable_so_zerocopy_check(fd); + + memset(sbuf1, 'x', sizeof(sbuf1)); + send_buf(fd, sbuf1, sizeof(sbuf1), 0, sizeof(sbuf1)); + + for (i =3D 0; i < sizeof(sbuf2); i++) + sbuf2[i] =3D rand() & 0xff; + + send_buf(fd, sbuf2, sizeof(sbuf2), MSG_ZEROCOPY, sizeof(sbuf2)); + + hash =3D hash_djb2(sbuf2, sizeof(sbuf2)); + control_writeulong(hash); + + fds.fd =3D fd; + fds.events =3D 0; + + if (poll(&fds, 1, TIMEOUT * MSEC_PER_SEC) !=3D 1 || + !(fds.revents & POLLERR)) { + perror("poll"); + exit(EXIT_FAILURE); + } + + close(fd); +} + +void test_stream_msgzcopy_mangle_server(const struct test_opts *opts) +{ + unsigned long local_hash, remote_hash; + char rbuf[PAGE_SIZE + 1]; + int fd; + + fd =3D vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL); + if (fd < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } + + /* Wait, don't race the (buggy) skbs coalescence. */ + vsock_ioctl_int(fd, SIOCINQ, PAGE_SIZE + 1 + GOOD_COPY_LEN); + + /* Discard the first packet. */ + recv_buf(fd, rbuf, PAGE_SIZE + 1, 0, PAGE_SIZE + 1); + + recv_buf(fd, rbuf, GOOD_COPY_LEN, 0, GOOD_COPY_LEN); + remote_hash =3D control_readulong(); + local_hash =3D hash_djb2(rbuf, GOOD_COPY_LEN); + + if (local_hash !=3D remote_hash) { + fprintf(stderr, "Data received corrupted\n"); + exit(EXIT_FAILURE); + } + + close(fd); +} diff --git a/tools/testing/vsock/vsock_test_zerocopy.h b/tools/testing/vsoc= k/vsock_test_zerocopy.h index 3ef2579e024d..d46c91a69f16 100644 --- a/tools/testing/vsock/vsock_test_zerocopy.h +++ b/tools/testing/vsock/vsock_test_zerocopy.h @@ -12,4 +12,7 @@ void test_seqpacket_msgzcopy_server(const struct test_opt= s *opts); void test_stream_msgzcopy_empty_errq_client(const struct test_opts *opts); void test_stream_msgzcopy_empty_errq_server(const struct test_opts *opts); =20 +void test_stream_msgzcopy_mangle_client(const struct test_opts *opts); +void test_stream_msgzcopy_mangle_server(const struct test_opts *opts); + #endif /* VSOCK_TEST_ZEROCOPY_H */ --=20 2.52.0