From nobody Mon Jun 8 16:29:06 2026 Received: from smtp808.umblergrid.com (smtp808.umblergrid.com [170.233.86.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 406DF3C0A19 for ; Wed, 27 May 2026 21:56:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.233.86.168 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779918970; cv=none; b=JDTpboz5tzcVfVGceIUVF/xi/Wy2eBsJ0L636ON+IdVEvApCb/Zw32o3wPMXoR4PX4MTkEfmMZlSCsuqEAqebVwN7iqcdxKqduq2JuSLttl/tDZeE+RGXQrMHnAJzPgDD+SF5rU8FF8ltUKVORpDpFtLBMMFYIozVzSjKSAxteg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779918970; c=relaxed/simple; bh=W85hRsaR4Ay2p42bOTW68FXUt2PIF0FAEiLZobz5M4s=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=KAtAq0adWwqD0T8rs2VqkdZTEvNMVWsvCeiLYIS7B1mpHQ3CrMHiNMAbHLEGlPJSlIoh3KfoYRA4N+ox/QNgm4/lRxkxa8fSg2MtaYC5Z2S6i/i3p/vZ+6vB4pCZ0Jd8pb+64/JGsk2AzFxTG+Sec6KDOpoInGGatmuTMXQMxws= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=henrybarreto.dev; spf=pass smtp.mailfrom=henrybarreto.dev; arc=none smtp.client-ip=170.233.86.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=henrybarreto.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=henrybarreto.dev Received: by smtp805.umblergrid.com id h2tjg03cs18n for ; Wed, 27 May 2026 18:29:33 -0300 (envelope-from ) Received: from UBMSA01.spo2.umbler.com (ubmsa01.spo2.umbler.com [187.84.237.185]) by UBCNTSCOUT01.umbler.com (8.15.2/8.15.2/Debian-8) with ESMTP id 64RLZjvX047188 for ; Wed, 27 May 2026 18:35:45 -0300 Received: by UBMSA01.spo2.umbler.com (Postfix, from userid 999) id 1A8FD200E0; Wed, 27 May 2026 18:35:45 -0300 (-03) Received: from dellg155510 (unknown [201.182.197.232]) by UBMSA01.spo2.umbler.com (Postfix) with ESMTPSA id 649792005E; Wed, 27 May 2026 18:35:31 -0300 (-03) From: Henry Barreto To: Richard Weinberger , Anton Ivanov Cc: Johannes Berg , Tiwei Bie , linux-um@lists.infradead.org, linux-kernel@vger.kernel.org, Henry Barreto Subject: [PATCH] um: vector: avoid NULL queue dereference in legacy RX mode Date: Wed, 27 May 2026 18:35:24 -0300 Message-ID: <20260527213524.45903-1-contato@henrybarreto.dev> X-Mailer: git-send-email 2.54.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Bayes-Prob: 0.0001 (Score 0, tokens from: outgoing, base:default, @@RPTN) Content-Type: text/plain; charset="utf-8" From: Henry Barreto Bringing a UML vector netdev up can panic in vector_net_open() with a fault in _raw_spin_lock(). vector_net_open() calls vector_reset_stats(), which takes the RX and TX queue locks. However, queue allocation depends on runtime transport options. With tap transport, vector RX/TX queues are not created and the legacy header buffers are used instead. Taking a queue lock then dereferences a NULL queue pointer. Take the queue locks in vector_reset_stats() only when the corresponding queue exists. Also move the RX queue lock in vector_poll() into the VECTOR_RX path, so legacy RX does not touch rx_queue. Fixes: 612a8c8e0b43 ("um: vector: Replace locks guarding queue depth with a= tomics") Signed-off-by: Henry Barreto Acked-By: Anton Ivanov --- arch/um/drivers/vector_kern.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index 25d9258fa592..70762f15d093 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -110,19 +110,26 @@ static void vector_reset_stats(struct vector_private = *vp) * in vector_poll. */ =20 - spin_lock(&vp->rx_queue->head_lock); + if (vp->rx_queue) + spin_lock(&vp->rx_queue->head_lock); + vp->estats.rx_queue_max =3D 0; vp->estats.rx_queue_running_average =3D 0; vp->estats.rx_encaps_errors =3D 0; vp->estats.sg_ok =3D 0; vp->estats.sg_linearized =3D 0; - spin_unlock(&vp->rx_queue->head_lock); + + if (vp->rx_queue) + spin_unlock(&vp->rx_queue->head_lock); + =20 /* TX stats are modified with TX head_lock held * in vector_send. */ =20 - spin_lock(&vp->tx_queue->head_lock); + if (vp->tx_queue) + spin_lock(&vp->tx_queue->head_lock); + vp->estats.tx_timeout_count =3D 0; vp->estats.tx_restart_queue =3D 0; vp->estats.tx_kicks =3D 0; @@ -130,7 +137,10 @@ static void vector_reset_stats(struct vector_private *= vp) vp->estats.tx_flow_control_xoff =3D 0; vp->estats.tx_queue_max =3D 0; vp->estats.tx_queue_running_average =3D 0; - spin_unlock(&vp->tx_queue->head_lock); + + if (vp->tx_queue) + spin_unlock(&vp->tx_queue->head_lock); + } =20 static int get_mtu(struct arglist *def) @@ -1168,15 +1178,15 @@ static int vector_poll(struct napi_struct *napi, in= t budget) =20 if ((vp->options & VECTOR_TX) !=3D 0) tx_enqueued =3D (vector_send(vp->tx_queue) > 0); - spin_lock(&vp->rx_queue->head_lock); - if ((vp->options & VECTOR_RX) > 0) + if ((vp->options & VECTOR_RX) > 0) { + spin_lock(&vp->rx_queue->head_lock); err =3D vector_mmsg_rx(vp, budget); - else { + spin_unlock(&vp->rx_queue->head_lock); + } else { err =3D vector_legacy_rx(vp); if (err > 0) err =3D 1; } - spin_unlock(&vp->rx_queue->head_lock); if (err > 0) work_done +=3D err; =20 --=20 2.54.0