Message ID | 20210905152109.1805619-1-willemdebruijn.kernel@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 8a0ed250f911da31a2aef52101bc707846a800ff |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net] ip_gre: validate csum_start only on pull | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Clearly marked for net |
netdev/subject_prefix | success | Link |
netdev/cc_maintainers | warning | 2 maintainers not CCed: yoshfuji@linux-ipv6.org dsahern@kernel.org |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 0 this patch: 0 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 29 lines checked |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/header_inline | success | Link |
On Sun, Sep 5, 2021 at 8:21 AM Willem de Bruijn <willemdebruijn.kernel@gmail.com> wrote: > > From: Willem de Bruijn <willemb@google.com> > > The GRE tunnel device can pull existing outer headers in ipge_xmit. > This is a rare path, apparently unique to this device. The below > commit ensured that pulling does not move skb->data beyond csum_start. > > But it has a false positive if ip_summed is not CHECKSUM_PARTIAL and > thus csum_start is irrelevant. > > Refine to exclude this. At the same time simplify and strengthen the > test. > > Simplify, by moving the check next to the offending pull, making it > more self documenting and removing an unnecessary branch from other > code paths. > > Strengthen, by also ensuring that the transport header is correct and > therefore the inner headers will be after skb_reset_inner_headers. > The transport header is set to csum_start in skb_partial_csum_set. > > Link: https://lore.kernel.org/netdev/YS+h%2FtqCJJiQei+W@shredder/ > Fixes: 1d011c4803c7 ("ip_gre: add validation for csum_start") > Reported-by: Ido Schimmel <idosch@idosch.org> > Suggested-by: Alexander Duyck <alexander.duyck@gmail.com> > Signed-off-by: Willem de Bruijn <willemb@google.com> > --- > net/ipv4/ip_gre.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c > index 177d26d8fb9c..0fe6c936dc54 100644 > --- a/net/ipv4/ip_gre.c > +++ b/net/ipv4/ip_gre.c > @@ -473,8 +473,6 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev, > > static int gre_handle_offloads(struct sk_buff *skb, bool csum) > { > - if (csum && skb_checksum_start(skb) < skb->data) > - return -EINVAL; > return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE); > } > > @@ -632,15 +630,20 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, > } > > if (dev->header_ops) { > + const int pull_len = tunnel->hlen + sizeof(struct iphdr); > + > if (skb_cow_head(skb, 0)) > goto free_skb; > > tnl_params = (const struct iphdr *)skb->data; > > + if (pull_len > skb_transport_offset(skb)) > + goto free_skb; > + > /* Pull skb since ip_tunnel_xmit() needs skb->data pointing > * to gre header. > */ > - skb_pull(skb, tunnel->hlen + sizeof(struct iphdr)); > + skb_pull(skb, pull_len); > skb_reset_mac_header(skb); > } else { > if (skb_cow_head(skb, dev->needed_headroom)) > -- > 2.33.0.153.gba50c8fa24-goog > Looks good to me. Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
On Sun, Sep 05, 2021 at 08:47:16AM -0700, Alexander Duyck wrote: > Looks good to me. > > Reviewed-by: Alexander Duyck <alexanderduyck@fb.com> Thanks Willem and Alex! Applied the patch to my tree. Will let you know tomorrow morning after regression is complete (though I'm sure it's fine).
Hello: This patch was applied to netdev/net.git (refs/heads/master): On Sun, 5 Sep 2021 11:21:09 -0400 you wrote: > From: Willem de Bruijn <willemb@google.com> > > The GRE tunnel device can pull existing outer headers in ipge_xmit. > This is a rare path, apparently unique to this device. The below > commit ensured that pulling does not move skb->data beyond csum_start. > > But it has a false positive if ip_summed is not CHECKSUM_PARTIAL and > thus csum_start is irrelevant. > > [...] Here is the summary with links: - [net] ip_gre: validate csum_start only on pull https://git.kernel.org/netdev/net/c/8a0ed250f911 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html
On Sun, Sep 05, 2021 at 11:21:09AM -0400, Willem de Bruijn wrote: > From: Willem de Bruijn <willemb@google.com> > > The GRE tunnel device can pull existing outer headers in ipge_xmit. > This is a rare path, apparently unique to this device. The below > commit ensured that pulling does not move skb->data beyond csum_start. > > But it has a false positive if ip_summed is not CHECKSUM_PARTIAL and > thus csum_start is irrelevant. > > Refine to exclude this. At the same time simplify and strengthen the > test. > > Simplify, by moving the check next to the offending pull, making it > more self documenting and removing an unnecessary branch from other > code paths. > > Strengthen, by also ensuring that the transport header is correct and > therefore the inner headers will be after skb_reset_inner_headers. > The transport header is set to csum_start in skb_partial_csum_set. > > Link: https://lore.kernel.org/netdev/YS+h%2FtqCJJiQei+W@shredder/ > Fixes: 1d011c4803c7 ("ip_gre: add validation for csum_start") > Reported-by: Ido Schimmel <idosch@idosch.org> > Suggested-by: Alexander Duyck <alexander.duyck@gmail.com> > Signed-off-by: Willem de Bruijn <willemb@google.com> FTR: Tested-by: Ido Schimmel <idosch@nvidia.com> Thanks
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 177d26d8fb9c..0fe6c936dc54 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -473,8 +473,6 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev, static int gre_handle_offloads(struct sk_buff *skb, bool csum) { - if (csum && skb_checksum_start(skb) < skb->data) - return -EINVAL; return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE); } @@ -632,15 +630,20 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, } if (dev->header_ops) { + const int pull_len = tunnel->hlen + sizeof(struct iphdr); + if (skb_cow_head(skb, 0)) goto free_skb; tnl_params = (const struct iphdr *)skb->data; + if (pull_len > skb_transport_offset(skb)) + goto free_skb; + /* Pull skb since ip_tunnel_xmit() needs skb->data pointing * to gre header. */ - skb_pull(skb, tunnel->hlen + sizeof(struct iphdr)); + skb_pull(skb, pull_len); skb_reset_mac_header(skb); } else { if (skb_cow_head(skb, dev->needed_headroom))