From nobody Thu Nov 12 15:08:50 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1793287788; cv=none; d=zohomail.com; s=zohoarc; b=HG249rgOXAgrT/zlyFyBveYWmV36aR5SPeXE0auPKxAfoaZCCcorrmtMSpcx9w8P2XfarlNglVPteDCgbKa9maJnMAigI6fXBzelPch4EkURXlTljhqLMSEjvZlEJBtmKEkISqMzg1LEUf680AxUtgPBI9Diw1Qssf4WCc1Szng= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1793287788; h=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:Subject:Subject:To:To:Message-Id:Cc; bh=5gjCFUj1BiEba0wlbwC58g6tHS+TNCDW16ThkCfazoM=; b=SO0iY/FpyseG9wBT2KXERj9JLkK70Ul4/UubId4D80kyL7hVUbrzE4fZ1s2jpyLOOqHPfeKB0Z7LxLvOWLtHMsksMEufSx4E84q+nMWwDrbQhBrfp3AAvccczaLrD2f2L9MVgam/2bnY4CIbj/LNPGa+Cpq0yBv9CrlHd9g0jvI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1793287788806968.8882103281641; Thu, 29 Oct 2026 08:29:48 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 49CFC41ADB; Thu, 29 Oct 2026 11:29:47 -0400 (EDT) Received: from [172.19.199.19] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 1B30841BE3; Thu, 29 Oct 2026 11:28:34 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 522413F975; Thu, 29 Oct 2026 11:28:24 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 83FA241AD3 for ; Thu, 29 Oct 2026 11:28:16 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-428-UiZRJ7qKMGmGYEPIYELzUA-1; Thu, 29 Oct 2026 11:28:14 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (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 mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9BEF1180ABEB for ; Thu, 29 Oct 2026 15:28:13 +0000 (UTC) Received: from mprivozn-thinkpadt14gen4.tpbc.csb (unknown [10.43.3.180]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 09C863000B56 for ; Thu, 29 Oct 2026 15:28:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1793287696; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5gjCFUj1BiEba0wlbwC58g6tHS+TNCDW16ThkCfazoM=; b=KPHRQnWTbYceztt/PGoEVhczp5POXRq7iYouzl8VsjKfH+vAvYmv6xawybA3+f5nMbVGZK mLP8JByG4zs1UiDgeZm+6HJDrF0ML5Pes4BeCsIAbZW/yaJtzKR5q83F3CDYlmTvd3ZEYA yniIBmrhtrDqJk7c3BWDA9dcWn3zOwk= X-MC-Unique: UiZRJ7qKMGmGYEPIYELzUA-1 X-Mimecast-MFC-AGG-ID: UiZRJ7qKMGmGYEPIYELzUA_1793287693 To: devel@lists.libvirt.org Subject: [PATCH] rpc: Deny REMOTE_PROC_AUTH_SASL_STEP without REMOTE_PROC_AUTH_SASL_START Date: Thu, 29 Oct 2026 16:28:09 +0100 Message-ID: <007b5a8372ffcc2fc38502f84eb2067645fe7e78.1793287689.git.mprivozn@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 40nZoHi29pdYbGC5_9ZUF9FFp70rMlDg1E-tA2XNGh4_1793287693 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 3R2JC6KASBO45SAC7HYFD6QGLZWWYLWJ X-Message-ID-Hash: 3R2JC6KASBO45SAC7HYFD6QGLZWWYLWJ X-MailFrom: mprivozn@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Michal Privoznik via Devel Reply-To: Michal Privoznik X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1793287790986158500 Content-Type: text/plain; charset="utf-8"; x-default="true" From: Michal Privoznik The usual flow of SASL is REMOTE_PROC_AUTH_SASL_INIT followed by REMOTE_PROC_AUTH_SASL_START which can either complete authentication or require further steps which are then done by calling REMOTE_PROC_AUTH_SASL_STEP (multiple times even). But if a malicious client skips the SASL_START step and calls SASL_INIT followed by SASL_STEP then the 'sasl->conn' structure inside of virNetSASLSessionServerStep() is not fully allocated (most notably the list of auth mechanisms 'mech' is NULL). But then sasl_server_step() dereferences that pointer leading to a crash. Fix this by disallowing SASL_STEP until SASL_START completed successfully. Fixes: CVE-2026-119151 Resolves: https://gitlab.com/libvirt/libvirt/-/work_items/940 Signed-off-by: Michal Privoznik --- src/libvirt_sasl.syms | 1 + src/remote/remote_daemon_dispatch.c | 8 +++++--- src/rpc/virnetsaslcontext.c | 25 +++++++++++++++++++++++++ src/rpc/virnetsaslcontext.h | 2 ++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/libvirt_sasl.syms b/src/libvirt_sasl.syms index 405ba1813e..c2a9144f0e 100644 --- a/src/libvirt_sasl.syms +++ b/src/libvirt_sasl.syms @@ -18,6 +18,7 @@ virNetSASLSessionExtKeySize; virNetSASLSessionGetIdentity; virNetSASLSessionGetKeySize; virNetSASLSessionGetMaxBufSize; +virNetSASLSessionIsStarted; virNetSASLSessionListMechanisms; virNetSASLSessionNewClient; virNetSASLSessionNewServer; diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon= _dispatch.c index e548438250..a813111c8d 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -3942,7 +3942,8 @@ remoteDispatchAuthSaslStart(virNetServer *server, =20 VIR_DEBUG("Start SASL auth %d", virNetServerClientGetFD(client)); if (virNetServerClientGetAuth(client) !=3D VIR_NET_SERVER_SERVICE_AUTH= _SASL || - priv->sasl =3D=3D NULL) { + priv->sasl =3D=3D NULL || + virNetSASLSessionIsStarted(priv->sasl)) { VIR_ERROR(_("client tried invalid SASL start request")); goto authfail; } @@ -4033,8 +4034,9 @@ remoteDispatchAuthSaslStep(virNetServer *server, =20 VIR_DEBUG("Step SASL auth %d", virNetServerClientGetFD(client)); if (virNetServerClientGetAuth(client) !=3D VIR_NET_SERVER_SERVICE_AUTH= _SASL || - priv->sasl =3D=3D NULL) { - VIR_ERROR(_("client tried invalid SASL start request")); + priv->sasl =3D=3D NULL || + !virNetSASLSessionIsStarted(priv->sasl)) { + VIR_ERROR(_("client tried invalid SASL step request")); goto authfail; } =20 diff --git a/src/rpc/virnetsaslcontext.c b/src/rpc/virnetsaslcontext.c index 8692703117..e6b57b7b95 100644 --- a/src/rpc/virnetsaslcontext.c +++ b/src/rpc/virnetsaslcontext.c @@ -43,6 +43,7 @@ struct _virNetSASLSession { sasl_conn_t *conn; size_t maxbufsize; sasl_callback_t *callbacks; + bool started; }; =20 =20 @@ -529,6 +530,13 @@ int virNetSASLSessionServerStart(virNetSASLSession *sa= sl, int ret =3D -1; =20 virObjectLock(sasl); + + if (sasl->started) { + virReportError(VIR_ERR_AUTH_FAILED, "%s", + _("unexpected state of SASL session")); + goto cleanup; + } + err =3D sasl_server_start(sasl->conn, mechname, clientin, @@ -542,13 +550,16 @@ int virNetSASLSessionServerStart(virNetSASLSession *s= asl, case SASL_OK: if (virNetSASLSessionUpdateBufSize(sasl) < 0) goto cleanup; + sasl->started =3D true; ret =3D VIR_NET_SASL_COMPLETE; break; case SASL_CONTINUE: ret =3D VIR_NET_SASL_CONTINUE; + sasl->started =3D true; break; case SASL_INTERACT: ret =3D VIR_NET_SASL_INTERACT; + sasl->started =3D true; break; default: virReportError(VIR_ERR_AUTH_FAILED, @@ -575,6 +586,13 @@ int virNetSASLSessionServerStep(virNetSASLSession *sas= l, int ret =3D -1; =20 virObjectLock(sasl); + + if (sasl->started =3D=3D false) { + virReportError(VIR_ERR_AUTH_FAILED, "%s", + _("unexpected state of SASL session")); + goto cleanup; + } + err =3D sasl_server_step(sasl->conn, clientin, inlen, @@ -707,6 +725,13 @@ void virNetSASLSessionDispose(void *obj) g_free(sasl->callbacks); } =20 +bool virNetSASLSessionIsStarted(virNetSASLSession *sasl) +{ + VIR_LOCK_GUARD lock =3D virObjectLockGuard(sasl); + + return sasl->started; +} + #ifdef __APPLE__ VIR_WARNINGS_RESET #endif diff --git a/src/rpc/virnetsaslcontext.h b/src/rpc/virnetsaslcontext.h index 7202822e5b..5bfb273e67 100644 --- a/src/rpc/virnetsaslcontext.h +++ b/src/rpc/virnetsaslcontext.h @@ -109,3 +109,5 @@ ssize_t virNetSASLSessionDecode(virNetSASLSession *sasl, size_t inputLen, const char **output, size_t *outputlen); + +bool virNetSASLSessionIsStarted(virNetSASLSession *sasl); --=20 2.56.0