Message ID | 1483721009.9712.14.camel@edumazet-glaptop3.roam.corp.google.com |
---|---|
State | Rejected, archived |
Delegated to: | David Miller |
Headers | show |
On Fri, 2017-01-06 at 08:43 -0800, Eric Dumazet wrote: > From: Eric Dumazet <edumazet@google.com> > > dccp_parse_options() improperly parses 12 or 16 bytes in excess, > because it forgets to subtract DCCP header len. > > This causes various issues, since these 12/16 bytes are part of the > payload and this might not even be present in skb->head, as > dccp_invalid_packet() only pulled everything but payload. > > KASAN complains since we might access uninitialized data. Scratch that. Never send a patch before first coffee in the morning ;)
diff --git a/net/dccp/options.c b/net/dccp/options.c index 74d29c56c36709fd4e31f0e63a1f8b1aa38a32cd..41bd4bc4026f97b155e12a3a37095653836ce7fc 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -54,10 +54,9 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, struct dccp_sock *dp = dccp_sk(sk); const struct dccp_hdr *dh = dccp_hdr(skb); const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type; - unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb); - unsigned char *opt_ptr = options; - const unsigned char *opt_end = (unsigned char *)dh + - (dh->dccph_doff * 4); + unsigned char *opt_ptr = (unsigned char *)dh + __dccp_hdr_len(dh); + unsigned int optlen = dh->dccph_doff * 4 - __dccp_hdr_len(dh); + const unsigned char *opt_end = opt_ptr + optlen; struct dccp_options_received *opt_recv = &dp->dccps_options_received; unsigned char opt, len; unsigned char *uninitialized_var(value);