In the Linux kernel, the following vulnerability has been resolved:
ipv6: avoid overflows in ip6_datagram_send_ctl()
Yiming Qian reported :
<quote>
I believe I found a locally triggerable kernel bug in the IPv6 sendmsg
ancillary-data path that can panic the kernel via skb_under_panic()
(local DoS).
The core issue is a mismatch between:
struct ipv6_txoptions::opt_flen, type
__u16) andopt->dst1opt)when multiple IPV6_DSTOPTS control messages (cmsgs) are provided.
include/net/ipv6.h:
struct ipv6_txoptions::opt_flen is __u16 (wrap possible).
(lines 291-307, especially 298)net/ipv6/datagram.c:ip6_datagram_send_ctl():
IPV6_DSTOPTS and accumulates into opt_flen
without rejecting duplicates. (lines 909-933)net/ipv6/ip6_output.c:__ip6_append_data():
opt->opt_flen + opt->opt_nflen to compute header
sizes/headroom decisions. (lines 1448-1466, especially 1463-1465)net/ipv6/ip6_output.c:__ip6_make_skb():
ipv6_push_frag_opts() if opt->opt_flen is non-zero.
(lines 1930-1934)net/ipv6/exthdrs.c:ipv6_push_frag_opts() / ipv6_push_exthdr():
ipv6_optlen(opt->dst1opt) (based on the
pointed-to header). (lines 1179-1185 and 1206-1211)opt_flen is a 16-bit accumulator:include/net/ipv6.h:298 defines __u16 opt_flen; /* after fragment hdr */.ip6_datagram_send_ctl() accepts repeated IPV6_DSTOPTS cmsgs
and increments opt_flen each time:net/ipv6/datagram.c:909-933, for IPV6_DSTOPTS:
len = ((hdr->hdrlen + 1) << 3);CAP_NET_RAW using ns_capable(net->user_ns, CAP_NET_RAW). (line 922)opt->opt_flen += len; (line 927)opt->dst1opt = hdr; (line 928)There is no duplicate rejection here (unlike the legacy
IPV6_2292DSTOPTS path which rejects...