From patchwork Wed Mar 15 12:55:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 13175808 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58F4DC61DA4 for ; Wed, 15 Mar 2023 12:56:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233090AbjCOM4j (ORCPT ); Wed, 15 Mar 2023 08:56:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233133AbjCOM4i (ORCPT ); Wed, 15 Mar 2023 08:56:38 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 252CD26AF for ; Wed, 15 Mar 2023 05:55:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1678884954; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=JaBgEDKfqWmVcH7ueaHiA2NEn4sgat0tMV862oPXgr4=; b=Iw4FYWWyUweuveIjmyV7BhU3HmCyG7I9Pr8o+X5wfKnCm+HBMEQ60Yh5lIR2aVUv6i6JB9 ajf1VST82QDNrITlrDE+nHTAq5A/z6EKcsLL6xcRWCFUKIAXDG9OzlAYizV0hCmMfdJqHf 1PoiC6t4yFJvkk3TWL2c0O2pCScfOd4= Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-583-aYcubN8LOmybI9eWPfdwew-1; Wed, 15 Mar 2023 08:55:53 -0400 X-MC-Unique: aYcubN8LOmybI9eWPfdwew-1 Received: by mail-ed1-f70.google.com with SMTP id z14-20020a05640235ce00b004e07ddbc2f8so26535378edc.7 for ; Wed, 15 Mar 2023 05:55:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678884952; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=JaBgEDKfqWmVcH7ueaHiA2NEn4sgat0tMV862oPXgr4=; b=HoGLu5kkfhrptGx8U09YW2qs8savcf34NQBWO93ttTOYNwLp2+ibz2LKWcHbB9/73w eHz+TNmICnn5teCayTUqFkteNHL8Zr891t+ZlfhDUzEdmwulTnG6BzK3RqSxKh9yqU4t p3a8dt38DBET2dRfSboh9bRL6JWQj8E8UsMJkwHPG6TI3iSdB/9BeUHUexw2hUcen8rH ppW4e8rWvnJb68uaQMKxAuyX3gfv2CKxHnDRNLOBaFYK5LMJJYI612S6Uk+2myyjdiex K4vNR2UonXQD1kvFPmk/bmZnhgunlOZZEVmp5BWgQB4iMG45FDlzPak0516KczqWTnGI QJZg== X-Gm-Message-State: AO0yUKW8taN++jxCHSYp7i3QD5yf5kqyEnUJjty2LgY958qgM5ERVgwz rTgUPq19G1ryNzHzRkmVQuwVFyKSg9kfBcH4pZOPwfH+AC7HQ/5AYv8o/F/Fad/2nOk4hWI4XDZ 13JrvqZ4+/+kN X-Received: by 2002:a17:906:5619:b0:879:ec1a:4ac with SMTP id f25-20020a170906561900b00879ec1a04acmr5309055ejq.76.1678884951903; Wed, 15 Mar 2023 05:55:51 -0700 (PDT) X-Google-Smtp-Source: AK7set92+fL8QpbWwG+iI45Vn0TA6DxsDamjpdhTlTEPG3PQ6xgwPGl4kxnIJbzVvn7UQ+LQTs+EeQ== X-Received: by 2002:a17:906:5619:b0:879:ec1a:4ac with SMTP id f25-20020a170906561900b00879ec1a04acmr5309031ejq.76.1678884951493; Wed, 15 Mar 2023 05:55:51 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([45.145.92.2]) by smtp.gmail.com with ESMTPSA id qa17-20020a170907869100b008cecb8f374asm2498501ejc.0.2023.03.15.05.55.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Mar 2023 05:55:51 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 355E69E2E8C; Wed, 15 Mar 2023 13:55:50 +0100 (CET) From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Igor Russkikh , Alexei Starovoitov , Daniel Borkmann , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , John Fastabend , Taehee Yoo Cc: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= , Freysteinn Alfredsson , Eric Dumazet , Paolo Abeni , netdev@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH net] net: atlantic: Fix crash when XDP is enabled but no program is loaded Date: Wed, 15 Mar 2023 13:55:38 +0100 Message-Id: <20230315125539.103319-1-toke@redhat.com> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The aq_xdp_run_prog() function falls back to the XDP_ABORTED action handler (using a goto) if the operations for any of the other actions fail. The XDP_ABORTED handler in turn calls the bpf_warn_invalid_xdp_action() tracepoint. However, the function also jumps into the XDP_PASS helper if no XDP program is loaded on the device, which means the XDP_ABORTED handler can be run with a NULL program pointer. This results in a NULL pointer deref because the tracepoint dereferences the 'prog' pointer passed to it. This situation can happen in multiple ways: - If a packet arrives between the removal of the program from the interface and the static_branch_dec() in aq_xdp_setup() - If there are multiple devices using the same driver in the system and one of them has an XDP program loaded and the other does not. Fix this by refactoring the aq_xdp_run_prog() function to remove the 'goto pass' handling if there is no XDP program loaded. Instead, factor out the skb building in a separate small helper function. Fixes: 26efaef759a1 ("net: atlantic: Implement xdp data plane") Reported-by: Freysteinn Alfredsson Tested-by: Freysteinn Alfredsson Signed-off-by: Toke Høiland-Jørgensen --- .../net/ethernet/aquantia/atlantic/aq_ring.c | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index 1e8d902e1c8e..7f933175cbda 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -412,6 +412,25 @@ int aq_xdp_xmit(struct net_device *dev, int num_frames, return num_frames - drop; } +static struct sk_buff *aq_xdp_build_skb(struct xdp_buff *xdp, + struct net_device *dev, + struct aq_ring_buff_s *buff) +{ + struct xdp_frame *xdpf; + struct sk_buff *skb; + + xdpf = xdp_convert_buff_to_frame(xdp); + if (unlikely(!xdpf)) + return NULL; + + skb = xdp_build_skb_from_frame(xdpf, dev); + if (!skb) + return NULL; + + aq_get_rxpages_xdp(buff, xdp); + return skb; +} + static struct sk_buff *aq_xdp_run_prog(struct aq_nic_s *aq_nic, struct xdp_buff *xdp, struct aq_ring_s *rx_ring, @@ -431,7 +450,7 @@ static struct sk_buff *aq_xdp_run_prog(struct aq_nic_s *aq_nic, prog = READ_ONCE(rx_ring->xdp_prog); if (!prog) - goto pass; + return aq_xdp_build_skb(xdp, aq_nic->ndev, buff); prefetchw(xdp->data_hard_start); /* xdp_frame write */ @@ -442,17 +461,12 @@ static struct sk_buff *aq_xdp_run_prog(struct aq_nic_s *aq_nic, act = bpf_prog_run_xdp(prog, xdp); switch (act) { case XDP_PASS: -pass: - xdpf = xdp_convert_buff_to_frame(xdp); - if (unlikely(!xdpf)) - goto out_aborted; - skb = xdp_build_skb_from_frame(xdpf, aq_nic->ndev); + skb = aq_xdp_build_skb(xdp, aq_nic->ndev, buff); if (!skb) goto out_aborted; u64_stats_update_begin(&rx_ring->stats.rx.syncp); ++rx_ring->stats.rx.xdp_pass; u64_stats_update_end(&rx_ring->stats.rx.syncp); - aq_get_rxpages_xdp(buff, xdp); return skb; case XDP_TX: xdpf = xdp_convert_buff_to_frame(xdp);