diff mbox series

[ipsec] esp6: fix check on ipv6_skip_exthdr's return value

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

Checks

Context Check Description
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix warning Target tree name not specified in the subject
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers fail 1 blamed authors not CCed: davem@davemloft.net; 5 maintainers not CCed: kuba@kernel.org dsahern@kernel.org herbert@gondor.apana.org.au yoshfuji@linux-ipv6.org davem@davemloft.net
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 9 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/tree_selection success Guessing tree name failed - patch did not apply

Commit Message

Sabrina Dubroca March 10, 2022, 10:49 a.m. UTC
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(-)

Comments

Steffen Klassert March 15, 2022, 12:58 p.m. UTC | #1
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 mbox series

Patch

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;
 		}