From nobody Tue Aug 1 20:04:36 2023 X-Original-To: dev-commits-src-branches@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 4RFmKs26P3z4pnrd; Tue, 1 Aug 2023 20:04:37 +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 4RFmKd2P3tz3GNT; Tue, 1 Aug 2023 20:04:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1690920277; 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=9fUQ1YDVCqI0d/nIke9/XDB6XugnwjBr6Zz0IzKfVq0=; b=WBeV7cYB72EQz4kzuuFj2hYfQBXOhvtrj/ZoSsfGHxW+HxVF0ZIh4ppp4wO1bxUfMaeztR aDeW2exzY2JI/xMRsx4vJd+US7DavJO1rcg5bP1zvX0spvNhWWpxfiQi3yPF3lCZZuhdlC SB5yaLg/axIrghWtr4MftjWDsiU05Y6wGnbi+MW056erErWr7t2ffa2vLU1QzFcs8yRJ80 5vIgiS3NGAKnM6RNxBecl3jzAOT0zNPBVKd+HS0dDeYwf1k5eh/DOUeNO+kJzG0C8rXnPo KM09wFKeSfma/LfXeyOWz3Xm2qOeFNKek3gu8FbfIQleNM6PRVJQOLzUWHnlvA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1690920277; a=rsa-sha256; cv=none; b=sw0dV8XOPr4wJc7sATn00H1a7Yi04EL1C6+44PGr4EN1ckj/D83G8/aqtr/6GE2ZqgfPEv 0mJIXg0HNWnj/YwLpuHLGOVWu5/03iiS3HwuKwTNi4kgXz41dWMRQcHgKrn3lFDHVN5yRG +6jMnb/4BR9w/SNQIcxwG5thJj6CljqalzSAwQkS94YLfOKBOZrj2tBuwf4mKVV/Cczq5R VtQfcoynNCvNYYqXHFiRBStGeJdEUjm+ptv7d6SvQncZqgZUiOGrXIvRk76Kj3Vgg92Bce PeNUanB5N5tGdh9qBRkTIicng40jIwZnfS7Vc9bPL4iAvO/gQ4fCYVo3zUrp7w== 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=1690920277; 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=9fUQ1YDVCqI0d/nIke9/XDB6XugnwjBr6Zz0IzKfVq0=; b=owWlt7pfNkHcZEFWu41MQ16jzx3LhBwJehMhL5z6b4a4AQRqmouRPBV3rSopAaocRigGKJ eX65w3fuihOo0xalApcxHjpoYhne+kKi1BKnDEFTg/Zyf/37NPhBt+1NX2dUsQu8soSlNR MrINZq3w6IVXl027lLvnHikrp8uqJokRVstiAA1EaTf1G1f+dNxLYCFgvxPn7r+1/Iqp6J bQO9k6orxrc3ZhU+Ef/1696+Q6RTxdx3jYDiIu1YUjNrEdaBCvfrFDeK1vcd1B9dK+wZ2r 6kTgwyWLLwm4/k47ap8unB0fPyL1FKHT6D5uyvUmLSMrZE3R08pb5791bSfKsQ== 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 4RFmKd0XGzzrD0; Tue, 1 Aug 2023 20:04:37 +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 371K4akJ013444; Tue, 1 Aug 2023 20:04:36 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 371K4a58013443; Tue, 1 Aug 2023 20:04:36 GMT (envelope-from git) Date: Tue, 1 Aug 2023 20:04:36 GMT Message-Id: <202308012004.371K4a58013443@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: 87702e38a4b4 - releng/13.1 - bhyve: Fully reset the fwctl state machine if the guest requests a reset. List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@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/releng/13.1 X-Git-Reftype: branch X-Git-Commit: 87702e38a4b4fe990b06f39b5cf267fb564c367e Auto-Submitted: auto-generated The branch releng/13.1 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=87702e38a4b4fe990b06f39b5cf267fb564c367e commit 87702e38a4b4fe990b06f39b5cf267fb564c367e Author: John Baldwin AuthorDate: 2023-06-29 18:27:12 +0000 Commit: Mark Johnston CommitDate: 2023-08-01 19:48:26 +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) (cherry picked from commit 9fe302d78109b12867bd933bb68cd900c9940b7d) --- usr.sbin/bhyve/fwctl.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/usr.sbin/bhyve/fwctl.c b/usr.sbin/bhyve/fwctl.c index 7c27d7e92532..d1ceed0e2daf 100644 --- a/usr.sbin/bhyve/fwctl.c +++ b/usr.sbin/bhyve/fwctl.c @@ -66,13 +66,12 @@ __FBSDID("$FreeBSD$"); /* * Back-end state-machine */ -enum state { - DORMANT, +static enum state { IDENT_WAIT, IDENT_SEND, REQ, RESP -} be_state = DORMANT; +} be_state; static uint8_t sig[] = { 'B', 'H', 'Y', 'V' }; static u_int ident_idx; @@ -203,7 +202,8 @@ static void fget_data(uint32_t data, uint32_t len) { - *((uint32_t *) &fget_str[fget_cnt]) = data; + assert(fget_cnt + sizeof(uint32_t) <= sizeof(fget_str)); + memcpy(&fget_str[fget_cnt], &data, sizeof(data)); fget_cnt += sizeof(uint32_t); } @@ -347,7 +347,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 @@ -445,6 +446,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. @@ -472,18 +495,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(); } }