From nobody Tue Aug 1 20:03:54 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4RFmJt2Hn1z4pnWN; Tue, 1 Aug 2023 20:03:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4RFmJq2gb4z3G56; Tue, 1 Aug 2023 20:03:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1690920235; 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=tTfwB1J7wezmenYJJrz2IPU2om1TQFXaZm9D5fdt5U8=; b=QO42P6s3C19clVdbgOWBGI7w0/m7CMa0XOdJsW0ksI7M9sCOXrnPHveBG81GGBXhX6f3fR 9Kbyevpw8ZHEHLcZ7lDxLfJXyheCquat0m08GrV3izx2D12mWeZqVQ8soDXOR8dRd3DRpj opRXJZBYQYks7Mh4vEEf7fqLog1Nvv/I9v+GZF2kIiWeo0jJXQ3DJ4rg3aVQJAxrQSWJMj Kx9GB2HhSyOpugSjQR2stTC99Ele4JM08PklPF22H4K0QHkOtdNrUM4XHkqNGxihTwYvwo F+D+EDeHVfKqNIUEAUcY7dsEii3RCrzxYJTB9pHJMAAQJoq7vwkENpz1sPTQAQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1690920235; a=rsa-sha256; cv=none; b=E3RPjoEoMPjvJobSpedVMN5MSjmvoqoxFtValpd03fEl2id0vajr0laziayOGUJeG/T7Po eWNXT6KebIgtGRShe37pNoh5a3ZN6jtSLNvvpmOrAnHa7lsRfMWmGx8oQGimLWINVpRXYx uhIi4TOzYuK7YIpcFIKThzU2B/kE8eNx3VvkY+mLTjlDEj+AZYVB+DPWz9oESmBO476Apx fZSYzX5bd3D0qXbSWVEu8JEc1mPDHZ+6GdvtdhB4gYqsn7aZdNNBm352baYDf4XxULkVYT 7aWfFE5BICemXs3359ZmnQBE03ixh26Vno3AIZq7mawyuA/u9iIOkgWPEL0CNQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1690920235; 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=tTfwB1J7wezmenYJJrz2IPU2om1TQFXaZm9D5fdt5U8=; b=GqbISdNMDPUEfdA+gr9S839D0FX2LSDdZ/e9hXtz4VZJPpTKR2MCbkuiKKfIhoPkYBCoxu AfHLLXYW9HKkmrtYfZ07m5GtT7S434oa0VzAbfxPSoVALC7u7aRahmT2ASvdFhMqow5nZ2 TmzGrMjrktb2Fwsw96SJH4Vg61KCxA6d7POcnTrKM6SCV0f9//pbBY1WsuCggs442kI3nZ JRGEEATHb0BRCryKAbVn3PKmS0hbcKN/p/331LCSF7jzbTPngkKEsQXCzFhbttNOfvohVC WHSzBXQeYy4gtv3Xdjzxy5xx4sMxTF3wEsi/jK/3w6XZvRjf+H0s/0bdN+kKaw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4RFmJp6DGSzr1S; Tue, 1 Aug 2023 20:03:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 371K3s1R012806; Tue, 1 Aug 2023 20:03:54 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 371K3sxL012805; Tue, 1 Aug 2023 20:03:54 GMT (envelope-from git) Date: Tue, 1 Aug 2023 20:03:54 GMT Message-Id: <202308012003.371K3sxL012805@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 9fe302d78109 - stable/13 - bhyve: Fully reset the fwctl state machine if the guest requests a reset. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 9fe302d78109b12867bd933bb68cd900c9940b7d Auto-Submitted: auto-generated The branch stable/13 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=9fe302d78109b12867bd933bb68cd900c9940b7d commit 9fe302d78109b12867bd933bb68cd900c9940b7d Author: John Baldwin AuthorDate: 2023-06-29 18:27:12 +0000 Commit: Mark Johnston CommitDate: 2023-08-01 19:48:53 +0000 bhyve: Fully reset the fwctl state machine if the guest requests a reset. If a guest tries to reset the fwctl device while a pending request was in flight, the fwctl state machine can be left in an incomplete state. Specifically, rinfo is not cleared. Normally the state machine for fwctl alternates between REQ (receiving request) and RESP (sending response) and ignores port writes while in RESP or port reads while in REQ. Once a guest completes the writes to the port to send a request, the state machine transitions to RESP and ignores future writes. However, if a guest writes a full request and then resets the fwctl device, the state would transition to REQ without draining the pending response or discarding the received request. Instead, additional port writes after the reset were treated as new payload bytes, but were appended to the previously-received request and could overflow the fget_str buffer. To fix, fully reset the fwctl state machine if the guest requests a reset. admbugs: 998 Approved by: so Reviewed by: markj Reported by: Omri Ben Bassat Security: FreeBSD-SA-23:07.bhyve Security: CVE-2023-3494 (cherry picked from commit bed3ae1d7863ac1e0b1e82ae7bf952937e921efe) --- usr.sbin/bhyve/fwctl.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/usr.sbin/bhyve/fwctl.c b/usr.sbin/bhyve/fwctl.c index 5227c06f0da7..24fedfab8885 100644 --- a/usr.sbin/bhyve/fwctl.c +++ b/usr.sbin/bhyve/fwctl.c @@ -67,12 +67,11 @@ __FBSDID("$FreeBSD$"); * Back-end state-machine */ static enum state { - DORMANT, IDENT_WAIT, IDENT_SEND, REQ, RESP -} be_state = DORMANT; +} be_state; static uint8_t sig[] = { 'B', 'H', 'Y', 'V' }; static u_int ident_idx; @@ -200,6 +199,7 @@ static void fget_data(uint32_t data, uint32_t len __unused) { + assert(fget_cnt + sizeof(uint32_t) <= sizeof(fget_str)); memcpy(&fget_str[fget_cnt], &data, sizeof(data)); fget_cnt += sizeof(uint32_t); } @@ -344,7 +344,8 @@ static int fwctl_request_data(uint32_t value) { - /* Make sure remaining size is >= 0 */ + /* Make sure remaining size is > 0 */ + assert(rinfo.req_size > 0); if (rinfo.req_size <= sizeof(uint32_t)) rinfo.req_size = 0; else @@ -441,6 +442,28 @@ fwctl_response(uint32_t *retval) return (0); } +static void +fwctl_reset(void) +{ + + switch (be_state) { + case RESP: + /* If a response was generated but not fully read, discard it. */ + fwctl_response_done(); + break; + case REQ: + /* Discard partially-received request. */ + memset(&rinfo, 0, sizeof(rinfo)); + break; + case IDENT_WAIT: + case IDENT_SEND: + break; + } + + be_state = IDENT_SEND; + ident_idx = 0; +} + /* * i/o port handling. @@ -468,18 +491,13 @@ fwctl_inb(void) static void fwctl_outw(uint16_t val) { - if (be_state == DORMANT) { - return; - } - if (val == 0) { /* * The guest wants to read the signature. It's possible that the * guest is unaware of the fwctl state at this moment. For that * reason, reset the state machine unconditionally. */ - be_state = IDENT_SEND; - ident_idx = 0; + fwctl_reset(); } }