From patchwork Wed Jun 21 14:15:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1797929 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=Aq1dJ5WJ; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QmQX80w7mz20Xm for ; Thu, 22 Jun 2023 00:15:50 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1qBycY-0007vo-3k; Wed, 21 Jun 2023 14:15:42 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1qBycV-0007vK-Qw for kernel-team@lists.ubuntu.com; Wed, 21 Jun 2023 14:15:39 +0000 Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 295CA3FFF2 for ; Wed, 21 Jun 2023 14:15:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1687356938; bh=at1/VKZo5MnOBamfGp/Iq1mvjpxS3g/FhPrle/nOkJI=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Aq1dJ5WJ4QXFn14mjVvY6j/SQVUEs9PI6OH5CVV35TiTXvbjvXKBDOvYyjamTfKew s0uV7Sfh1JX0ZWGGv6oF+kVxHXZavjRNTSf9a3m2Dm29OFMZz5lbM+tppfTJgz8qZ6 BUnqLHBNtvJT5U7xR9eRl+tvQgRz5LXjyyW36vGVjvL/kZvcqE9TYv/dUSmWOd/9IH AbesM4XyB2D1K7lpSEhgqCj/Q2Bb+7ml8668Pisb8EAlylfN3TcIiUBX27b3zN3PO9 n2NXIL9bd3itriRGUTAPSig9+6nzb01625I3aayfm7S96JpvV5No1NAcYnp4GA7mOT h0aRQJFcAPTgg== Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-3f8fe1f1199so21660325e9.0 for ; Wed, 21 Jun 2023 07:15:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687356937; x=1689948937; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=at1/VKZo5MnOBamfGp/Iq1mvjpxS3g/FhPrle/nOkJI=; b=UdXvVp0aALRu2bQXeCDqW1VVqVuTCvLFxS0pKw4HrETLME3eHnsK8r30VtdT8kFfs9 P8pszJX+0QPMgdb7rN2eG+JkFdvk3QGU43vIAxyNL9rsCLgRDTWu09ikQI3KXC4Dru70 IuX9HG9lb3GPQcy35h+x4b3V8lBMxi97GbtXjheJgxmhNcB0rghPha8lmd4gr/mvVwVB 8qv0wzP5PltZGg9cfF7GKn5w8aKzKh/PkVChtgqmwRl1Bklukp75/Py2LlzK0CewY+Ye fWtrc3ZICkx7bPatD0fFs1klEiU207byoNQo2cUkM9bH0t8hEKxCfOlKsvNlaC801j1w 0rdQ== X-Gm-Message-State: AC+VfDzwLsyrH+QWBbMRipSXcGNcBr+mmjhVf/Kedxk2M9jifaH2J2XF 6o6l5g7G+twzug7TdoAggJMUawx2QSyjoQDqu67WVgeUGVuNsNarzcnou8j2FDXqUCblN8FLJ25 o4tt+6MjRQzWdEjhaK14tyD3DhF3v45C8WCVtqpR+nHcOiv8AH0bv X-Received: by 2002:a05:600c:28f:b0:3f9:866:80cd with SMTP id 15-20020a05600c028f00b003f9086680cdmr8158214wmk.41.1687356937451; Wed, 21 Jun 2023 07:15:37 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5Q+/zo1jXbl1I3Ap7si/QZKCqXBuyryfBo2uvwvZ3qERn/eGRC+UbAd1yVTXU8edzSY56TxA== X-Received: by 2002:a05:600c:28f:b0:3f9:866:80cd with SMTP id 15-20020a05600c028f00b003f9086680cdmr8158192wmk.41.1687356937100; Wed, 21 Jun 2023 07:15:37 -0700 (PDT) Received: from localhost ([92.44.150.68]) by smtp.gmail.com with ESMTPSA id p24-20020a1c7418000000b003f9c859894esm1071655wmc.7.2023.06.21.07.15.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 07:15:36 -0700 (PDT) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU OEM-5.17, OEM-6.0 PATCH 1/1] net: sched: disallow noqueue for qdisc classes Date: Wed, 21 Jun 2023 17:15:28 +0300 Message-Id: <20230621141528.1034485-2-cengiz.can@canonical.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230621141528.1034485-1-cengiz.can@canonical.com> References: <20230621141528.1034485-1-cengiz.can@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Frederick Lawler While experimenting with applying noqueue to a classful queue discipline, we discovered a NULL pointer dereference in the __dev_queue_xmit() path that generates a kernel OOPS: # dev=enp0s5 # tc qdisc replace dev $dev root handle 1: htb default 1 # tc class add dev $dev parent 1: classid 1:1 htb rate 10mbit # tc qdisc add dev $dev parent 1:1 handle 10: noqueue # ping -I $dev -w 1 -c 1 1.1.1.1 [ 2.172856] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 2.173217] #PF: supervisor instruction fetch in kernel mode ... [ 2.178451] Call Trace: [ 2.178577] [ 2.178686] htb_enqueue+0x1c8/0x370 [ 2.178880] dev_qdisc_enqueue+0x15/0x90 [ 2.179093] __dev_queue_xmit+0x798/0xd00 [ 2.179305] ? _raw_write_lock_bh+0xe/0x30 [ 2.179522] ? __local_bh_enable_ip+0x32/0x70 [ 2.179759] ? ___neigh_create+0x610/0x840 [ 2.179968] ? eth_header+0x21/0xc0 [ 2.180144] ip_finish_output2+0x15e/0x4f0 [ 2.180348] ? dst_output+0x30/0x30 [ 2.180525] ip_push_pending_frames+0x9d/0xb0 [ 2.180739] raw_sendmsg+0x601/0xcb0 [ 2.180916] ? _raw_spin_trylock+0xe/0x50 [ 2.181112] ? _raw_spin_unlock_irqrestore+0x16/0x30 [ 2.181354] ? get_page_from_freelist+0xcd6/0xdf0 [ 2.181594] ? sock_sendmsg+0x56/0x60 [ 2.181781] sock_sendmsg+0x56/0x60 [ 2.181958] __sys_sendto+0xf7/0x160 [ 2.182139] ? handle_mm_fault+0x6e/0x1d0 [ 2.182366] ? do_user_addr_fault+0x1e1/0x660 [ 2.182627] __x64_sys_sendto+0x1b/0x30 [ 2.182881] do_syscall_64+0x38/0x90 [ 2.183085] entry_SYSCALL_64_after_hwframe+0x63/0xcd ... [ 2.187402] Previously in commit d66d6c3152e8 ("net: sched: register noqueue qdisc"), NULL was set for the noqueue discipline on noqueue init so that __dev_queue_xmit() falls through for the noqueue case. This also sets a bypass of the enqueue NULL check in the register_qdisc() function for the struct noqueue_disc_ops. Classful queue disciplines make it past the NULL check in __dev_queue_xmit() because the discipline is set to htb (in this case), and then in the call to __dev_xmit_skb(), it calls into htb_enqueue() which grabs a leaf node for a class and then calls qdisc_enqueue() by passing in a queue discipline which assumes ->enqueue() is not set to NULL. Fix this by not allowing classes to be assigned to the noqueue discipline. Linux TC Notes states that classes cannot be set to the noqueue discipline. [1] Let's enforce that here. Links: 1. https://linux-tc-notes.sourceforge.net/tc/doc/sch_noqueue.txt Fixes: d66d6c3152e8 ("net: sched: register noqueue qdisc") Cc: stable@vger.kernel.org Signed-off-by: Frederick Lawler Reviewed-by: Jakub Sitnicki Link: https://lore.kernel.org/r/20230109163906.706000-1-fred@cloudflare.com Signed-off-by: Jakub Kicinski CVE-2022-47929 (cherry picked from commit 96398560f26aa07e8f2969d73c8197e6a6d10407) Signed-off-by: Cengiz Can --- net/sched/sch_api.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 67ee8ae3f310..bb9542a516ac 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1114,6 +1114,11 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, return -ENOENT; } + if (new && new->ops == &noqueue_qdisc_ops) { + NL_SET_ERR_MSG(extack, "Cannot assign noqueue to a class"); + return -EINVAL; + } + err = cops->graft(parent, cl, new, &old, extack); if (err) return err;