CVE-2023-35847 (published 2023-06-19T03:15Z)

VirtualSquare picoTCP (aka PicoTCP-NG) through 2.1 does not have an MSS lower bound (e.g., it could be zero).

CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-908
cwe_name: Use of Uninitialized Resource
description: The product uses or accesses a resource that has not been initialized.
extended_description: When a resource has not been properly initialized, the product may behave unexpectedly. This may lead to a crash or invalid memory access, but the consequences vary depending on the type of resource and how it is used within the product.
         

Fix information:
repo_url: https://github.com/virtualsquare/picotcp
commit_details: repo_url: https://github.com/virtualsquare/picotcp
author: Daniele Lacamera
author_date: 2023-05-12 22:24:11+02:00
msg: TCP: Fixed MSS size calculation. Set MSS lower bound.

Reported-by: "P. Amsuo, Purdue University"
repository: repo_url: https://github.com/virtualsquare/picotcp
repo_name: virtualsquare/picotcp
repo_language: C
owner: virtualsquare
file_changes: filename: pico_tcp.c
change_type: ModificationType.MODIFY
diff: @@ -1085,7 +1085,11 @@ struct pico_socket *pico_tcp_open(struct pico_stack *S, uint16_t family)
     t->sock.stack = S;
     t->sock.timestamp = TCP_TIME;
     pico_socket_set_family(&t->sock, family);
-    t->mss = (uint16_t)(pico_socket_get_mss(&t->sock) - PICO_SIZE_TCPHDR);
+    t->mss = (uint16_t)(pico_socket_get_mss(&t->sock));
+    if (t->mss > PICO_SIZE_TCPHDR + PICO_TCP_MIN_MSS)
+        t->mss -= (uint16_t)PICO_SIZE_TCPHDR;
+    else
+        t->mss = PICO_TCP_MIN_MSS;
     t->tcpq_in.pool.root = t->tcpq_hold.pool.root = t->tcpq_out.pool.root = &LEAF;
     t->tcpq_hold.pool.compare = t->tcpq_out.pool.compare = segment_compare;
     t->tcpq_in.pool.compare = input_segment_compare;
@@ -1254,7 +1258,10 @@ int pico_tcp_initconn(struct pico_socket *s)
     ts->snd_last = ts->snd_nxt;
     ts->cwnd = PICO_TCP_IW;
     mtu = (uint16_t)pico_socket_get_mss(s);
-    ts->mss = (uint16_t)(mtu - PICO_SIZE_TCPHDR);
+    if (mtu > PICO_SIZE_TCPHDR + PICO_TCP_MIN_MSS)
+        ts->mss = (uint16_t)(mtu - PICO_SIZE_TCPHDR);
+    else
+        ts->mss = PICO_TCP_MIN_MSS;
     ts->ssthresh = (uint16_t)((uint16_t)(PICO_DEFAULT_SOCKETQ / ts->mss) -  (((uint16_t)(PICO_DEFAULT_SOCKETQ / ts->mss)) >> 3u));
     syn->sock = s;
     hdr->seq = long_be(ts->snd_nxt);
@@ -2446,7 +2453,10 @@ static int tcp_syn(struct pico_socket *s, struct pico_frame *f)
 #endif
     f->sock = &new->sock;
     mtu = (uint16_t)pico_socket_get_mss(&new->sock);
-    new->mss = (uint16_t)(mtu - PICO_SIZE_TCPHDR);
+    if (mtu > PICO_SIZE_TCPHDR + PICO_TCP_MIN_MSS)
+        new->mss = (uint16_t)(mtu - PICO_SIZE_TCPHDR);
+    else
+        new->mss = PICO_TCP_MIN_MSS;
     if (tcp_parse_options(f) < 0)
         return -1;
     new->sock.stack = s->stack;

programming_language: C
filename: pico_tcp.h
change_type: ModificationType.MODIFY
diff: @@ -55,6 +55,7 @@ PACKED_STRUCT_DEF tcp_pseudo_hdr_ipv4
 #define PICO_TCPHDR_SIZE 20
 #define PICO_SIZE_TCPOPT_SYN 20
 #define PICO_SIZE_TCPHDR (uint32_t)(sizeof(struct pico_tcp_hdr))
+#define PICO_TCP_MIN_MSS (64 - PICO_SIZE_TCPHDR)
 
 /* TCP options */
 #define PICO_TCP_OPTION_END         0x00

programming_language: C