From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=a4FoVZRE; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by passt.top (Postfix) with ESMTPS id 0ACEF5A0265 for ; Fri, 06 Mar 2026 11:52:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772794350; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZHCeJZ7RrcPcggEWcFbcRqTGcGCwz05Ut2Hqj5U2HDM=; b=a4FoVZRE/qx9xewwmzENNXkMVETwUqh2byoM4MuD41F2pUEIsS9Oi+ml/MVte5SdeLwYeB wk0XRyBQ0JxZPd+8hgFNUXZ3pH6WTQFFvWxnh0Z583z7HlRDCiueplsNXJxC/zbbtM3X7b WIfBD3dNlv0D6hfVjRhzQmPdgwGzqIg= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-460-WiamzZuWNeCpga_x2g7EMA-1; Fri, 06 Mar 2026 05:52:29 -0500 X-MC-Unique: WiamzZuWNeCpga_x2g7EMA-1 X-Mimecast-MFC-AGG-ID: WiamzZuWNeCpga_x2g7EMA_1772794348 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4836bf1a920so97339295e9.3 for ; Fri, 06 Mar 2026 02:52:29 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772794347; x=1773399147; h=date:content-transfer-encoding:mime-version:organization:references :in-reply-to:message-id:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ETO2u5IOk14CXPo6/OwVL4QT6Q4NjIDsDQZDQ/WHHag=; b=uVX8TFdWRmmEm55GkUujC0GyO2KfcsZuFKL9Sz3xoxfzTe3qV6sf3XPAM5+Z1oRHEu 1V1wrVe9B0lbLqE/8ZdsvQGA3eAahyX6nfTrRQ6LPE6qZuFAKz6I3VQf91rgC2ZJVYJS zFUJi21Qt6Wm2GMVkcCeY+E4PvHcM4d9kDUtVPD27PF2oHXRwDKPsHfLKGs28mtUVXT7 2UTDMniKmUcOx4ly3PXpqNgrV4AoQPad+WoMdmLcXOlN52tU79xAm/JRxfubE6ZOCFhC 8AXmCinh21zp140o86TT5xzmbYu0d/R14bH57dxrK7bAmBPissK1uVKHde2TL8KZgxZ2 cCTw== X-Gm-Message-State: AOJu0YwGRduZZ0myIQxElLXpz/kU2mijnccPrvRv+ark6oBQWKr34oLo iDCX9QrhWPkEOzQCTLXuJS4n0Yy1Cxgj8tnBOAHrY0bFuycVOIll4b5euyu60mi/9YkH3E26F/s vxGIruJsQzteX/OBUxnP65V6ej0L5QYQU2SQhz6qC/P37Nr7P2GFQIK08uYjz2g== X-Gm-Gg: ATEYQzxlwWfyPYanEWLHPRAEI4Kz0LaLwlx8If2EqUiuCESNwiKE16qOeflH/gTlSYc l5qDzhrgN70xZgEDrrAWOxb4mFoFQH4AN1DNnn2cUihAOfqcqDzzZS3Z5otBe5D7sCjcbN5BNAS /ZgntzLITqB2HOUIGlK+PHhxH/AAVBMgJji4YDLZS5/rrWB5uVDh3DMJsyZIwZrDmvVJcs+0qw5 i616dO85GX7NH8eJDhtUiQHC6envCzM/E3x9+GxWtd8PTBV6gv6d7ZE41ovEQsFtvQJDlmwIUaY oPeflQtYokCI3kNnzcZ5Hph4erluzXoM7zxkulKTnpiEZyz+wt5KWWEk2TslEhXfV7mBND6npPi Y5/viE+VwlyWd5y37oVBnMFjWMb0vUPp/17x9rLHFutA7/Mygzg== X-Received: by 2002:a05:600c:8115:b0:477:a219:cdb7 with SMTP id 5b1f17b1804b1-485268bd69fmr28193645e9.0.1772794347403; Fri, 06 Mar 2026 02:52:27 -0800 (PST) X-Received: by 2002:a05:600c:8115:b0:477:a219:cdb7 with SMTP id 5b1f17b1804b1-485268bd69fmr28193155e9.0.1772794346844; Fri, 06 Mar 2026 02:52:26 -0800 (PST) Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [176.103.220.4]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4852687c1ecsm20893405e9.1.2026.03.06.02.52.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Mar 2026 02:52:26 -0800 (PST) From: Stefano Brivio To: Laurent Vivier Subject: Re: [PATCH v3] iov: Add iov_truncate() helper and use it in vu handlers Message-ID: <20260306115224.787f7bd0@elisabeth> In-Reply-To: <8dd07b62-b7d1-46c6-8378-da8e11d81a67@redhat.com> References: <20260305125648.3720714-1-lvivier@redhat.com> <20260306083530.56648725@elisabeth> <20260306092504.54432a5f@elisabeth> <28c1ce99-b58a-48c7-9ab8-53bd8926809f@redhat.com> <8dd07b62-b7d1-46c6-8378-da8e11d81a67@redhat.com> Organization: Red Hat X-Mailer: Claws Mail 4.2.0 (GTK 3.24.49; x86_64-pc-linux-gnu) MIME-Version: 1.0 Date: Fri, 06 Mar 2026 11:52:25 +0100 (CET) X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: CdPTKUXHv0ZS-0_tNQUdXf-_8fjwRqbpurQQ3bCbRFE_1772794348 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: AYJXRM3ZNTMGXCT75MIMR3ZFDWXEESU6 X-Message-ID-Hash: AYJXRM3ZNTMGXCT75MIMR3ZFDWXEESU6 X-MailFrom: sbrivio@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top, David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: On Fri, 6 Mar 2026 11:41:17 +0100 Laurent Vivier wrote: > On 3/6/26 09:51, Laurent Vivier wrote: > > On 3/6/26 09:25, Stefano Brivio wrote: =20 > >> On Fri, 6 Mar 2026 09:17:32 +0100 > >> Laurent Vivier wrote: > >> =20 > >>> On 3/6/26 08:35, Stefano Brivio wrote: =20 > >>>> On Thu,=C2=A0 5 Mar 2026 13:56:48 +0100 > >>>> Laurent Vivier wrote: =20 > >>>>> Add a generic iov_truncate() function that truncates an IO vector t= o a > >>>>> given number of bytes, returning the number of iov entries that con= tain > >>>>> data after truncation. > >>>>> > >>>>> Use it in udp_vu_sock_recv() and tcp_vu_sock_recv() to replace the > >>>>> open-coded truncation logic that adjusted iov entries after recvmsg= (). > >>>>> Also convert the direct iov_len assignment in tcp_vu_send_flag() to= use > >>>>> iov_truncate() for consistency. > >>>>> > >>>>> Signed-off-by: Laurent Vivier > >>>>> --- > >>>>> > >>>>> Notes: > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 v3: use in tcp_vu_send_flag() too > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 v2: use iov_truncate() in udp_vu_soc= k_recv() too > >>>>> > >>>>> =C2=A0=C2=A0 iov.c=C2=A0=C2=A0=C2=A0 | 22 ++++++++++++++++++++++ > >>>>> =C2=A0=C2=A0 iov.h=C2=A0=C2=A0=C2=A0 |=C2=A0 1 + > >>>>> =C2=A0=C2=A0 tcp_vu.c | 14 +++----------- > >>>>> =C2=A0=C2=A0 udp_vu.c | 12 +++--------- > >>>>> =C2=A0=C2=A0 4 files changed, 29 insertions(+), 20 deletions(-) > >>>>> > >>>>> diff --git a/iov.c b/iov.c > >>>>> index ad726daa4cd8..31a3f5bc29e5 100644 > >>>>> --- a/iov.c > >>>>> +++ b/iov.c > >>>>> @@ -147,6 +147,28 @@ size_t iov_size(const struct iovec *iov, size_= t iov_cnt) > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return len; > >>>>> =C2=A0=C2=A0 } > >>>>> +/** > >>>>> + * iov_truncate() - Truncate an IO vector to a given number of byt= es > >>>>> + * @iov:=C2=A0=C2=A0=C2=A0 IO vector (modified) > >>>>> + * @iov_cnt:=C2=A0=C2=A0=C2=A0 Number of entries in @iov > >>>>> + * @size:=C2=A0=C2=A0=C2=A0 Total number of bytes to keep > >>>>> + * > >>>>> + * Return: number of iov entries that contain data after truncatio= n > >>>>> + */ > >>>>> +size_t iov_truncate(struct iovec *iov, size_t iov_cnt, size_t size= ) > >>>>> +{ > >>>>> +=C2=A0=C2=A0=C2=A0 size_t i, offset; > >>>>> + > >>>>> +=C2=A0=C2=A0=C2=A0 i =3D iov_skip_bytes(iov, iov_cnt, size, &offse= t); > >>>>> + > >>>>> +=C2=A0=C2=A0=C2=A0 if (i < iov_cnt) { > >>>>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 iov[i].iov_len =3D offs= et; > >>>>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 i +=3D !!offset; > >>>>> +=C2=A0=C2=A0=C2=A0 } > >>>>> + > >>>>> +=C2=A0=C2=A0=C2=A0 return i; > >>>>> +} > >>>>> + > >>>>> =C2=A0=C2=A0 /** > >>>>> =C2=A0=C2=A0=C2=A0 * iov_tail_prune() - Remove any unneeded buffers= from an IOV tail > >>>>> =C2=A0=C2=A0=C2=A0 * @tail:=C2=A0=C2=A0=C2=A0 IO vector tail (modif= ied) > >>>>> diff --git a/iov.h b/iov.h > >>>>> index d1ab91a94e22..b4e50b0fca5a 100644 > >>>>> --- a/iov.h > >>>>> +++ b/iov.h > >>>>> @@ -29,6 +29,7 @@ size_t iov_from_buf(const struct iovec *iov, size= _t iov_cnt, > >>>>> =C2=A0=C2=A0 size_t iov_to_buf(const struct iovec *iov, size_t iov_= cnt, > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 size_t offset, void *buf, size_t bytes); > >>>>> =C2=A0=C2=A0 size_t iov_size(const struct iovec *iov, size_t iov_cn= t); > >>>>> +size_t iov_truncate(struct iovec *iov, size_t iov_cnt, size_t size= ); > >>>>> =C2=A0=C2=A0 /* > >>>>> =C2=A0=C2=A0=C2=A0 * DOC: Theory of Operation, struct iov_tail > >>>>> diff --git a/tcp_vu.c b/tcp_vu.c > >>>>> index 88be232dca66..8ca4170f13f6 100644 > >>>>> --- a/tcp_vu.c > >>>>> +++ b/tcp_vu.c > >>>>> @@ -131,7 +131,7 @@ int tcp_vu_send_flag(const struct ctx *c, struc= t tcp_tap_conn=20 > >>>>> *conn, int flags) > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return= ret; > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } > >>>>> -=C2=A0=C2=A0=C2=A0 flags_elem[0].in_sg[0].iov_len =3D hdrlen + opt= len; > >>>>> +=C2=A0=C2=A0=C2=A0 iov_truncate(&flags_iov[0], 1, hdrlen + optlen)= ; > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 payload =3D IOV_TAIL(flags_ele= m[0].in_sg, 1, hdrlen); > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (flags & KEEPALIVE) > >>>>> @@ -192,9 +192,9 @@ static ssize_t tcp_vu_sock_recv(const struct ct= x *c, struct=20 > >>>>> vu_virtq *vq, > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 struct msghdr mh_sock =3D { 0 = }; > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 uint16_t mss =3D MSS_GET(conn)= ; > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 int s =3D conn->sock; > >>>>> -=C2=A0=C2=A0=C2=A0 ssize_t ret, len; > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 size_t hdrlen; > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 int elem_cnt; > >>>>> +=C2=A0=C2=A0=C2=A0 ssize_t ret; > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 int i; > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *iov_cnt =3D 0; > >>>>> @@ -247,15 +247,7 @@ static ssize_t tcp_vu_sock_recv(const struct c= tx *c, struct=20 > >>>>> vu_virtq *vq, > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ret -= =3D already_sent; > >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* adjust iov number and lengt= h of the last iov */ > >>>>> -=C2=A0=C2=A0=C2=A0 len =3D ret; > >>>>> -=C2=A0=C2=A0=C2=A0 for (i =3D 0; len && i < elem_cnt; i++) { > >>>>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 struct iovec *iov =3D &= elem[i].in_sg[0]; > >>>>> - > >>>>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (iov->iov_len > (siz= e_t)len) > >>>>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= iov->iov_len =3D len; > >>>>> - > >>>>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 len -=3D iov->iov_len; > >>>>> -=C2=A0=C2=A0=C2=A0 } > >>>>> +=C2=A0=C2=A0=C2=A0 i =3D iov_truncate(&iov_vu[DISCARD_IOV_NUM], el= em_cnt, ret); =20 > >>>> > >>>> I had a quick look, but I couldn't figure this out. This causes > >>>> Coverity Scan to report: > >>>> > >>>> /home/sbrivio/passt/tcp_vu.c:457:3: > >>>> =C2=A0=C2=A0=C2=A0 Type: Overflowed constant (INTEGER_OVERFLOW) > >>>> > >>>> /home/sbrivio/passt/tcp_vu.c:355:2: > >>>> =C2=A0=C2=A0=C2=A0 1. path: Condition "!vu_queue_enabled(vq)", takin= g false branch. > >>>> /home/sbrivio/passt/tcp_vu.c:355:2: > >>>> =C2=A0=C2=A0=C2=A0 2. path: Condition "!vu_queue_started(vq)", takin= g false branch. > >>>> /home/sbrivio/passt/tcp_vu.c:362:2: > >>>> =C2=A0=C2=A0=C2=A0 3. path: Condition "0U /* (uint32_t)0 */ - (uint3= 2_t)already_sent - 1 <=20 > >>>> (16777216U /* 1 << 16 + 8 */)", taking false branch. > >>>> /home/sbrivio/passt/tcp_vu.c:374:2: > >>>> =C2=A0=C2=A0=C2=A0 4. path: Condition "!wnd_scaled", taking false br= anch. > >>>> /home/sbrivio/passt/tcp_vu.c:374:2: > >>>> =C2=A0=C2=A0=C2=A0 5. path: Condition "already_sent >=3D wnd_scaled"= , taking false branch. > >>>> /home/sbrivio/passt/tcp_vu.c:388:2: > >>>> =C2=A0=C2=A0=C2=A0 6. path: Condition "v6", taking true branch. > >>>> /home/sbrivio/passt/tcp_vu.c:390:2: > >>>> =C2=A0=C2=A0=C2=A0 7. path: Condition "len < 0", taking false branch= . > >>>> /home/sbrivio/passt/tcp_vu.c:402:2: > >>>> =C2=A0=C2=A0=C2=A0 8. path: Condition "!len", taking false branch. > >>>> /home/sbrivio/passt/tcp_vu.c:425:2: > >>>> =C2=A0=C2=A0=C2=A0 9. path: Condition "log_trace", taking true branc= h. > >>>> /home/sbrivio/passt/tcp_vu.c:426:2: > >>>> =C2=A0=C2=A0=C2=A0 10. path: Condition "log_trace", taking true bran= ch. > >>>> /home/sbrivio/passt/tcp_vu.c:439:2: > >>>> =C2=A0=C2=A0=C2=A0 11. path: Condition "v6", taking true branch. > >>>> /home/sbrivio/passt/tcp_vu.c:439:2: > >>>> =C2=A0=C2=A0=C2=A0 12. function_return: Function "tcp_vu_hdrlen(v6)"= returns 86. > >>>> /home/sbrivio/passt/tcp_vu.c:439:2: > >>>> =C2=A0=C2=A0=C2=A0 13. known_value_assign: "hdrlen" =3D "tcp_vu_hdrl= en(v6)", its value is now 86. > >>>> /home/sbrivio/passt/tcp_vu.c:440:2: > >>>> =C2=A0=C2=A0=C2=A0 14. path: Condition "i < head_cnt", taking true b= ranch. > >>>> /home/sbrivio/passt/tcp_vu.c:443:3: > >>>> =C2=A0=C2=A0=C2=A0 15. function_return: Function "iov_size(iov, buf_= cnt)" returns 0. > >>>> /home/sbrivio/passt/tcp_vu.c:443:3: > >>>> =C2=A0=C2=A0=C2=A0 16. known_value_assign: "dlen" =3D "iov_size(iov,= buf_cnt) - hdrlen", its value is=20 > >>>> now 18446744073709551530. > >>>> /home/sbrivio/passt/tcp_vu.c:450:3: > >>>> =C2=A0=C2=A0=C2=A0 17. path: Condition "previous_dlen !=3D dlen", ta= king true branch. > >>>> /home/sbrivio/passt/tcp_vu.c:454:3: > >>>> =C2=A0=C2=A0=C2=A0 18. path: Condition "!*c->pcap", taking false bra= nch. > >>>> /home/sbrivio/passt/tcp_vu.c:457:3: > >>>> =C2=A0=C2=A0=C2=A0 19. overflow_const: Expression "dlen + hdrlen", w= here "dlen" is known to be equal=20 > >>>> to -86,=C2=A0 and "hdrlen" is known to be equal to 86, underflows th= e type of "dlen +=20 > >>>> hdrlen", which is type "unsigned long". =20 > >>> > >>> if iov_size(iov, buf_cnt) =3D 0 and hdrlen =3D 86 (all unsigned) > >>> "dlen" =3D "iov_size(iov, buf_cnt) - hdrlen", its value is now 184467= 44073709551530 (see > >>> 16.) (i.e. -hdrlen, unsigned -86) > >>> so "dlen + hdrlen" overflows (I guess). =20 > >> > >> I was also thinking it was something like that but: > >> =20 > >>> > >>> Try: > >>> diff --git a/tcp_vu.c b/tcp_vu.c > >>> index 8ca4170f13f6..787ee004a66a 100644 > >>> --- a/tcp_vu.c > >>> +++ b/tcp_vu.c > >>> @@ -440,7 +440,7 @@ int tcp_vu_data_from_sock(const struct ctx *c, st= ruct tcp_tap_conn=20 > >>> *conn) > >>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 for (i =3D 0, = previous_dlen =3D -1, check =3D NULL; i < head_cnt; i++) { > >>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 struct iovec *iov =3D &elem[head[i]].in_s= g[0]; > >>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 int buf_cnt =3D head[i + 1] - head[i]; > >>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 ssize_t dlen =3D iov_size(iov, buf_cnt) - hdrlen; > >>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 ssize_t dlen =3D (ssize_t)iov_size(iov, buf_cnt) - hdrle= n; > >>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 bool push =3D i =3D=3D head_cnt - 1; > >>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 size_t l2len; =20 > >> > >> ...still not happy because of how we use dlen later (I think?): > >> > >> /home/sbrivio/passt/tcp_vu.c:457:3: > >> =C2=A0=C2=A0 Type: Overflowed constant (INTEGER_OVERFLOW) > >> > >> /home/sbrivio/passt/tcp_vu.c:355:2: > >> =C2=A0=C2=A0 1. path: Condition "!vu_queue_enabled(vq)", taking false = branch. > >> /home/sbrivio/passt/tcp_vu.c:355:2: > >> =C2=A0=C2=A0 2. path: Condition "!vu_queue_started(vq)", taking false = branch. > >> /home/sbrivio/passt/tcp_vu.c:362:2: > >> =C2=A0=C2=A0 3. path: Condition "0U /* (uint32_t)0 */ - (uint32_t)alre= ady_sent - 1 < (16777216U /*=20 > >> 1 << 16 + 8 */)", taking false branch. > >> /home/sbrivio/passt/tcp_vu.c:374:2: > >> =C2=A0=C2=A0 4. path: Condition "!wnd_scaled", taking false branch. > >> /home/sbrivio/passt/tcp_vu.c:374:2: > >> =C2=A0=C2=A0 5. path: Condition "already_sent >=3D wnd_scaled", taking= false branch. > >> /home/sbrivio/passt/tcp_vu.c:388:2: > >> =C2=A0=C2=A0 6. path: Condition "v6", taking true branch. > >> /home/sbrivio/passt/tcp_vu.c:390:2: > >> =C2=A0=C2=A0 7. path: Condition "len < 0", taking false branch. > >> /home/sbrivio/passt/tcp_vu.c:402:2: > >> =C2=A0=C2=A0 8. path: Condition "!len", taking false branch. > >> /home/sbrivio/passt/tcp_vu.c:425:2: > >> =C2=A0=C2=A0 9. path: Condition "log_trace", taking true branch. > >> /home/sbrivio/passt/tcp_vu.c:426:2: > >> =C2=A0=C2=A0 10. path: Condition "log_trace", taking true branch. > >> /home/sbrivio/passt/tcp_vu.c:439:2: > >> =C2=A0=C2=A0 11. path: Condition "v6", taking true branch. > >> /home/sbrivio/passt/tcp_vu.c:440:2: > >> =C2=A0=C2=A0 12. path: Condition "i < head_cnt", taking true branch. > >> /home/sbrivio/passt/tcp_vu.c:443:3: > >> =C2=A0=C2=A0 13. known_value_assign: "dlen" =3D "(ssize_t)iov_size(iov= , buf_cnt) - hdrlen", its=20 > >> value is now 18446744073709551530. > >> /home/sbrivio/passt/tcp_vu.c:450:3: > >> =C2=A0=C2=A0 14. path: Condition "previous_dlen !=3D dlen", taking tru= e branch. > >> /home/sbrivio/passt/tcp_vu.c:454:3: > >> =C2=A0=C2=A0 15. path: Condition "!*c->pcap", taking false branch. > >> /home/sbrivio/passt/tcp_vu.c:457:3: > >> =C2=A0=C2=A0 16. overflow_const: Expression "dlen + hdrlen", where "dl= en" is known to be equal to=20 > >> -86,=C2=A0 and "hdrlen" is known to be equal to 86, underflows the typ= e of "dlen + hdrlen",=20 > >> which is type "unsigned long". > >> > >> /home/sbrivio/passt/conf.c:2373:4: > >> =C2=A0=C2=A0 Type: Untrusted value as argument (TAINTED_SCALAR) > >> =20 > >=20 > > Could you try: > > diff --git a/tcp_vu.c b/tcp_vu.c > > index 8ca4170f13f6..fd734e857b3b 100644 > > --- a/tcp_vu.c > > +++ b/tcp_vu.c > > @@ -440,10 +440,14 @@ int tcp_vu_data_from_sock(const struct ctx *c, st= ruct tcp_tap_conn=20 > > *conn) > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 for (i =3D 0, previous_dlen= =3D -1, check =3D NULL; i < head_cnt; i++) { > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 struct iovec *iov =3D &elem[head[i]].in_sg[0]; > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 int buf_cnt =3D head[i + 1] - head[i]; > > -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 ssize_t dlen =3D iov_size(iov, buf_cnt) - hdrlen; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 size_t frame_size =3D iov_size(iov, buf_cnt); > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 bool push =3D i =3D=3D head_cnt - 1; > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 ssize_t dlen; > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 size_t l2len; > >=20 > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 ASSERT(frame_size >=3D hdrlen); > > + > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 dlen =3D frame_size - hdrlen; > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 vu_set_vnethdr(iov->iov_base, buf_cnt); > >=20 > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 /* The IPv4 header checksum varies only with dlen */ > >=20 > > Coverity likes "ASSERT()"... =20 >=20 > This seems to fix the problem for me. >=20 > Do you want a separate patch or to merge with this one? A separate patch would be nice, so that I don't have to convert spaces back to tabs myself, and I guess it might deserve a new review anyway... --=20 Stefano