[PATCH net v2] strparser: Fix signed/unsigned mismatch bug

Nate Karstens posted 1 patch 1 month, 1 week ago
net/strparser/strparser.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH net v2] strparser: Fix signed/unsigned mismatch bug
Posted by Nate Karstens 1 month, 1 week ago
The `len` member of the sk_buff is an unsigned int. This is cast to
`ssize_t` (a signed type) for the first sk_buff in the comparison,
but not the second sk_buff. On 32-bit systems, this can result in
an integer underflow for certain values because unsigned arithmetic
is being used.

This appears to be an oversight: if the intention was to use unsigned
arithmetic, then the first cast would have been omitted. The change
ensures both len values are cast to `ssize_t`.

The underflow causes an issue with ktls when multiple TLS PDUs are
included in a single TCP segment. The mainline kernel does not use
strparser for ktls anymore, but this is still useful for other
features that still use strparser, and for backporting.

Signed-off-by: Nate Karstens <nate.karstens@garmin.com>
Cc: stable@vger.kernel.org
Fixes: 43a0c6751a32 ("strparser: Stream parser for messages")
---
 net/strparser/strparser.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c
index 43b1f558b33d..e659fea2da70 100644
--- a/net/strparser/strparser.c
+++ b/net/strparser/strparser.c
@@ -238,7 +238,7 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
 				strp_parser_err(strp, -EMSGSIZE, desc);
 				break;
 			} else if (len <= (ssize_t)head->len -
-					  skb->len - stm->strp.offset) {
+					  (ssize_t)skb->len - stm->strp.offset) {
 				/* Length must be into new skb (and also
 				 * greater than zero)
 				 */
-- 
2.34.1
Re: [PATCH net v2] strparser: Fix signed/unsigned mismatch bug
Posted by Sabrina Dubroca 1 month, 1 week ago
2025-11-06, 16:28:33 -0600, Nate Karstens wrote:
> The `len` member of the sk_buff is an unsigned int. This is cast to
> `ssize_t` (a signed type) for the first sk_buff in the comparison,
> but not the second sk_buff. On 32-bit systems, this can result in
> an integer underflow for certain values because unsigned arithmetic
> is being used.
> 
> This appears to be an oversight: if the intention was to use unsigned
> arithmetic, then the first cast would have been omitted. The change
> ensures both len values are cast to `ssize_t`.
> 
> The underflow causes an issue with ktls when multiple TLS PDUs are
> included in a single TCP segment. The mainline kernel does not use
> strparser for ktls anymore, but this is still useful for other
> features that still use strparser, and for backporting.
> 
> Signed-off-by: Nate Karstens <nate.karstens@garmin.com>
> Cc: stable@vger.kernel.org
> Fixes: 43a0c6751a32 ("strparser: Stream parser for messages")
> ---
>  net/strparser/strparser.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>

Thanks Nate.

-- 
Sabrina
Re: [PATCH net v2] strparser: Fix signed/unsigned mismatch bug
Posted by Jacob Keller 1 month, 1 week ago

On 11/6/2025 2:28 PM, Nate Karstens wrote:
> The `len` member of the sk_buff is an unsigned int. This is cast to
> `ssize_t` (a signed type) for the first sk_buff in the comparison,
> but not the second sk_buff. On 32-bit systems, this can result in
> an integer underflow for certain values because unsigned arithmetic
> is being used.
> 
> This appears to be an oversight: if the intention was to use unsigned
> arithmetic, then the first cast would have been omitted. The change
> ensures both len values are cast to `ssize_t`.
> 
> The underflow causes an issue with ktls when multiple TLS PDUs are
> included in a single TCP segment. The mainline kernel does not use
> strparser for ktls anymore, but this is still useful for other
> features that still use strparser, and for backporting.
> 
> Signed-off-by: Nate Karstens <nate.karstens@garmin.com>
> Cc: stable@vger.kernel.org
> Fixes: 43a0c6751a32 ("strparser: Stream parser for messages")
> ---

Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>

>  net/strparser/strparser.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c
> index 43b1f558b33d..e659fea2da70 100644
> --- a/net/strparser/strparser.c
> +++ b/net/strparser/strparser.c
> @@ -238,7 +238,7 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
>  				strp_parser_err(strp, -EMSGSIZE, desc);
>  				break;
>  			} else if (len <= (ssize_t)head->len -
> -					  skb->len - stm->strp.offset) {
> +					  (ssize_t)skb->len - stm->strp.offset) {
>  				/* Length must be into new skb (and also
>  				 * greater than zero)
>  				 */