Message ID | 4215f33e156b9bf7259d3efb5c7b888f45c7f9b8.1646748826.git.sd@queasysnail.net (mailing list archive) |
---|---|
State | Awaiting Upstream |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [ipsec] esp6: fix check on ipv6_skip_exthdr's return value | expand |
On Thu, Mar 10, 2022 at 11:49:00AM +0100, Sabrina Dubroca wrote: > Commit 5f9c55c8066b ("ipv6: check return value of ipv6_skip_exthdr") > introduced an incorrect check, which leads to all ESP packets over > either TCPv6 or UDPv6 encapsulation being dropped. In this particular > case, offset is negative, since skb->data points to the ESP header in > the following chain of headers, while skb->network_header points to > the IPv6 header: > > IPv6 | ext | ... | ext | UDP | ESP | ... > > That doesn't seem to be a problem, especially considering that if we > reach esp6_input_done2, we're guaranteed to have a full set of headers > available (otherwise the packet would have been dropped earlier in the > stack). However, it means that the return value will (intentionally) > be negative. We can make the test more specific, as the expected > return value of ipv6_skip_exthdr will be the (negated) size of either > a UDP header, or a TCP header with possible options. > > In the future, we should probably either make ipv6_skip_exthdr > explicitly accept negative offsets (and adjust its return value for > error cases), or make ipv6_skip_exthdr only take non-negative > offsets (and audit all callers). > > Fixes: 5f9c55c8066b ("ipv6: check return value of ipv6_skip_exthdr") > Reported-by: Xiumei Mu <xmu@redhat.com> > Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Applied, thanks a lot Sabrina!
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index b0ffbcd5432d..55d604c9b3b3 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -812,8 +812,7 @@ int esp6_input_done2(struct sk_buff *skb, int err) struct tcphdr *th; offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off); - - if (offset < 0) { + if (offset == -1) { err = -EINVAL; goto out; }
Commit 5f9c55c8066b ("ipv6: check return value of ipv6_skip_exthdr") introduced an incorrect check, which leads to all ESP packets over either TCPv6 or UDPv6 encapsulation being dropped. In this particular case, offset is negative, since skb->data points to the ESP header in the following chain of headers, while skb->network_header points to the IPv6 header: IPv6 | ext | ... | ext | UDP | ESP | ... That doesn't seem to be a problem, especially considering that if we reach esp6_input_done2, we're guaranteed to have a full set of headers available (otherwise the packet would have been dropped earlier in the stack). However, it means that the return value will (intentionally) be negative. We can make the test more specific, as the expected return value of ipv6_skip_exthdr will be the (negated) size of either a UDP header, or a TCP header with possible options. In the future, we should probably either make ipv6_skip_exthdr explicitly accept negative offsets (and adjust its return value for error cases), or make ipv6_skip_exthdr only take non-negative offsets (and audit all callers). Fixes: 5f9c55c8066b ("ipv6: check return value of ipv6_skip_exthdr") Reported-by: Xiumei Mu <xmu@redhat.com> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> --- net/ipv6/esp6.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)