From patchwork Thu Feb 14 18:39:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Oskolkov X-Patchwork-Id: 1042348 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="qI7FiST7"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 440lYS4hHxz9s7T for ; Fri, 15 Feb 2019 05:39:40 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405089AbfBNSji (ORCPT ); Thu, 14 Feb 2019 13:39:38 -0500 Received: from mail-qt1-f202.google.com ([209.85.160.202]:51877 "EHLO mail-qt1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391235AbfBNSji (ORCPT ); Thu, 14 Feb 2019 13:39:38 -0500 Received: by mail-qt1-f202.google.com with SMTP id 65so6419311qte.18 for ; Thu, 14 Feb 2019 10:39:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=zYra66/hcNwWgAt3WHyYRXgA/4ZCs2FXQ2IPENp3U5k=; b=qI7FiST7LZHFYsZoAs69IOsyOKH8GUix1SixR1lEWAZDU4JSfsDNz3IrSanchIRBWW RYPmBBNjhF78OLT7vAHCzFM/rNvY6mT13GxtMEsSrii5DznwJ7V6EvCLiYPLWEJ3k0R4 M2JEVYHRpElP6Z6HTSK72t6VgMianYZfyHPQnLEzklZNnsyZeC5olEeYtBISlsZGNl+5 juNid0PqsU89AzKHM9/hDdJX4uTONXKkPTjeU+g88T6C3sRAPB3A4M7g/TiMeki3dCE6 Krwu+FJEIRUONHgo8pMl126RNyquAVOrkmmxri6c1ygbJDFoGNP7m0RANe6u2F36jeji F6hA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=zYra66/hcNwWgAt3WHyYRXgA/4ZCs2FXQ2IPENp3U5k=; b=PbmXuy71n9Ofnqcgc2J+mD5zBgNc7l+kC+Ag/dcWTZMEvd/7qbxcI4pB+VSM9qPjDk eN8DmQjJ8cku6HBbcVgKS2yLGT5MBMHpeegqEmQelpIjsuAPsajpaTKDN81pvwRJokTj 7WasxkG1ZgSx0xb070Rzbdm8lBiXDyajBpoycpZOhQbQIqItRG/bf5mUpWV09uDlMpuN NYoev5umFlmnob+GcyQDMpQEE8J9kZ0ga0dJk92b/yNa8VCzUoBXv9oFLuJTdFoRxr2x lDFNF2EY8vjTdiwpjWsu40TVR/k2FjCuop+OuyfyHWGi4t/lY07pusiseDlB1yZ/p8CL q2sg== X-Gm-Message-State: AHQUAua0K6JPFEmGsUcy/UgJq3OUKQHehV4JAn0uamBe+9+n0hx3UPYw SQBnxf0IfGWBpIs8lKnJ02mPSAEV X-Google-Smtp-Source: AHgI3IYdFHrmToutf48xUUkwIeeunC1Y3uvA6yHDU4nFNcO4ueGqqiTUL5GaABF7+gExOhTr+PzVXipn X-Received: by 2002:a37:a3c8:: with SMTP id m191mr2992803qke.20.1550169577613; Thu, 14 Feb 2019 10:39:37 -0800 (PST) Date: Thu, 14 Feb 2019 10:39:31 -0800 Message-Id: <20190214183931.20293-1-posk@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.21.0.rc0.258.g878e2cd30e-goog Subject: [PATCH bpf-next v2] bpf: fix memory leak in bpf_lwt_xmit_reroute From: Peter Oskolkov To: Alexei Starovoitov , Daniel Borkmann , netdev@vger.kernel.org Cc: Peter Oskolkov , David Ahern , Willem de Bruijn , Peter Oskolkov Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On error the skb should be freed. Tested with diff/steps provided by David Ahern. v2: surface routing errors to the user instead of a generic EINVAL, as suggested by David Ahern. Reported-by: David Ahern Fixes: 3bd0b15281af ("bpf: add handling of BPF_LWT_REROUTE to lwt_bpf.c") Signed-off-by: Peter Oskolkov Reviewed-by: David Ahern --- net/core/lwt_bpf.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c index 32251f3fcda0..a5c8c79d468a 100644 --- a/net/core/lwt_bpf.c +++ b/net/core/lwt_bpf.c @@ -179,17 +179,17 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb) struct net_device *l3mdev = l3mdev_master_dev_rcu(skb_dst(skb)->dev); int oif = l3mdev ? l3mdev->ifindex : 0; struct dst_entry *dst = NULL; + int err = -EAFNOSUPPORT; struct sock *sk; struct net *net; bool ipv4; - int err; if (skb->protocol == htons(ETH_P_IP)) ipv4 = true; else if (skb->protocol == htons(ETH_P_IPV6)) ipv4 = false; else - return -EAFNOSUPPORT; + goto err; sk = sk_to_full_sk(skb->sk); if (sk) { @@ -215,8 +215,10 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb) fl4.saddr = iph->saddr; rt = ip_route_output_key(net, &fl4); - if (IS_ERR(rt)) - return -EINVAL; + if (IS_ERR(rt)) { + err = PTR_ERR(rt); + goto err; + } dst = &rt->dst; } else { struct ipv6hdr *iph6 = ipv6_hdr(skb); @@ -231,12 +233,17 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb) fl6.saddr = iph6->saddr; err = ipv6_stub->ipv6_dst_lookup(net, skb->sk, &dst, &fl6); - if (err || IS_ERR(dst)) - return -EINVAL; + if (unlikely(err)) + goto err; + if (IS_ERR(dst)) { + err = PTR_ERR(dst); + goto err; + } } if (unlikely(dst->error)) { + err = dst->error; dst_release(dst); - return -EINVAL; + goto err; } /* Although skb header was reserved in bpf_lwt_push_ip_encap(), it @@ -246,17 +253,21 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb) */ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev)); if (unlikely(err)) - return err; + goto err; skb_dst_drop(skb); skb_dst_set(skb, dst); err = dst_output(dev_net(skb_dst(skb)->dev), skb->sk, skb); if (unlikely(err)) - return err; + goto err; /* ip[6]_finish_output2 understand LWTUNNEL_XMIT_DONE */ return LWTUNNEL_XMIT_DONE; + +err: + kfree_skb(skb); + return err; } static int bpf_xmit(struct sk_buff *skb)