picotcp: Discard incoming TCP segments with zero-len options
upstream
7aa288510a
This commit is contained in:
parent
f0aa1abf89
commit
6853238c8b
|
@ -882,7 +882,7 @@ static inline void tcp_parse_option_timestamp(struct pico_socket_tcp *t, struct
|
|||
t->ts_nxt = long_be(tsval);
|
||||
}
|
||||
|
||||
static void tcp_parse_options(struct pico_frame *f)
|
||||
static int tcp_parse_options(struct pico_frame *f)
|
||||
{
|
||||
struct pico_socket_tcp *t = (struct pico_socket_tcp *)f->sock;
|
||||
uint8_t *opt = f->transport_hdr + PICO_SIZE_TCPHDR;
|
||||
|
@ -899,6 +899,10 @@ static void tcp_parse_options(struct pico_frame *f)
|
|||
if (f->payload && ((opt + i) > f->payload))
|
||||
break;
|
||||
|
||||
if (len == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcp_dbg_options("Received option '%d', len = %d \n", type, len);
|
||||
switch (type) {
|
||||
case PICO_TCP_OPTION_NOOP:
|
||||
|
@ -926,6 +930,7 @@ static void tcp_parse_options(struct pico_frame *f)
|
|||
i = i + len - 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void tcp_send_add_tcpflags(struct pico_socket_tcp *ts, struct pico_frame *f)
|
||||
|
@ -1757,7 +1762,8 @@ static int tcp_data_in(struct pico_socket *s, struct pico_frame *f)
|
|||
(void)hdr;
|
||||
|
||||
if (((hdr->len & 0xf0u) >> 2u) <= f->transport_len) {
|
||||
tcp_parse_options(f);
|
||||
if (tcp_parse_options(f) < 0)
|
||||
return -1;
|
||||
f->payload = f->transport_hdr + ((hdr->len & 0xf0u) >> 2u);
|
||||
f->payload_len = payload_len;
|
||||
tcp_dbg("TCP> Received segment. (exp: %x got: %x)\n", t->rcv_nxt, SEQN(f));
|
||||
|
@ -2132,7 +2138,8 @@ static int tcp_ack(struct pico_socket *s, struct pico_frame *f)
|
|||
tcp_ack_dbg(s, f);
|
||||
#endif
|
||||
|
||||
tcp_parse_options(f);
|
||||
if (tcp_parse_options(f) < 0)
|
||||
return -1;
|
||||
t->recv_wnd = short_be(hdr->rwnd);
|
||||
|
||||
acked = (uint16_t)tcp_ack_advance_una(t, f, &acked_timestamp);
|
||||
|
@ -2448,7 +2455,8 @@ static int tcp_syn(struct pico_socket *s, struct pico_frame *f)
|
|||
f->sock = &new->sock;
|
||||
mtu = (uint16_t)pico_socket_get_mss(&new->sock);
|
||||
new->mss = (uint16_t)(mtu - PICO_SIZE_TCPHDR);
|
||||
tcp_parse_options(f);
|
||||
if (tcp_parse_options(f) < 0)
|
||||
return -1;
|
||||
new->tcpq_in.max_size = PICO_DEFAULT_SOCKETQ;
|
||||
new->tcpq_out.max_size = PICO_DEFAULT_SOCKETQ;
|
||||
new->tcpq_hold.max_size = 2u * mtu;
|
||||
|
@ -2866,6 +2874,11 @@ int pico_tcp_input(struct pico_socket *s, struct pico_frame *f)
|
|||
// tcp_dbg("[sam] TCP> s->state >> 8 = %u\n", s->state >> 8);
|
||||
tcp_dbg("[tcp input] socket: %p state: %d <-- local port:%u remote port: %u seq: 0x%08x ack: 0x%08x flags: 0x%02x t_len: %u, hdr: %u payload: %d\n", s, s->state >> 8, short_be(hdr->trans.dport), short_be(hdr->trans.sport), SEQN(f), ACKN(f), hdr->flags, f->transport_len, (hdr->len & 0xf0) >> 2, f->payload_len );
|
||||
|
||||
if ((f->payload + f->payload_len) > (f->buffer + f->buffer_len)) {
|
||||
tcp_dbg("TCP> Invalid payload len %04x\n", f->payload_len);
|
||||
pico_frame_discard(f);
|
||||
return -1;
|
||||
}
|
||||
/* This copy of the frame has the current socket as owner */
|
||||
f->sock = s;
|
||||
s->timestamp = TCP_TIME;
|
||||
|
|
Loading…
Reference in New Issue