mirror of https://gitee.com/openkylin/linux.git
ipv6: fix EFAULT on sendto with icmpv6 and hdrincl
The following code returns EFAULT (Bad address): s = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); setsockopt(s, SOL_IPV6, IPV6_HDRINCL, 1); sendto(ipv6_icmp6_packet, addr); /* returns -1, errno = EFAULT */ The IPv4 equivalent code works. A workaround is to use IPPROTO_RAW instead of IPPROTO_ICMPV6. The failure happens because 2 bytes are eaten from the msghdr by rawv6_probe_proto_opt() starting from commit19e3c66b52
("ipv6 equivalent of "ipv4: Avoid reading user iov twice after raw_probe_proto_opt""), but at that time it was not a problem because IPV6_HDRINCL was not yet introduced. Only eat these 2 bytes if hdrincl == 0. Fixes:715f504b11
("ipv6: add IPV6_HDRINCL option for raw sockets") Signed-off-by: Olivier Matz <olivier.matz@6wind.com> Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
59e3e4b526
commit
b9aa52c4cb
|
@ -895,11 +895,14 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||||
opt = ipv6_fixup_options(&opt_space, opt);
|
opt = ipv6_fixup_options(&opt_space, opt);
|
||||||
|
|
||||||
fl6.flowi6_proto = proto;
|
fl6.flowi6_proto = proto;
|
||||||
rfv.msg = msg;
|
|
||||||
rfv.hlen = 0;
|
if (!hdrincl) {
|
||||||
err = rawv6_probe_proto_opt(&rfv, &fl6);
|
rfv.msg = msg;
|
||||||
if (err)
|
rfv.hlen = 0;
|
||||||
goto out;
|
err = rawv6_probe_proto_opt(&rfv, &fl6);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ipv6_addr_any(daddr))
|
if (!ipv6_addr_any(daddr))
|
||||||
fl6.daddr = *daddr;
|
fl6.daddr = *daddr;
|
||||||
|
|
Loading…
Reference in New Issue