From owner-dev-commits-src-branches@freebsd.org Wed Feb 24 15:02:42 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id A256455F17B; Wed, 24 Feb 2021 15:02:42 +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 4Dlzg64Fpvz3N9m; Wed, 24 Feb 2021 15:02:42 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 849FA2E04F; Wed, 24 Feb 2021 15:02:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 11OF2gCC013441; Wed, 24 Feb 2021 15:02:42 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 11OF2gOw013440; Wed, 24 Feb 2021 15:02:42 GMT (envelope-from git) Date: Wed, 24 Feb 2021 15:02:42 GMT Message-Id: <202102241502.11OF2gOw013440@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mitchell Horne Subject: git: 8837e9c54072 - stable/13 - arm64: validate breakpoint registers MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mhorne X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 8837e9c54072679b69ae0c0345e7ef7d241255aa Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Feb 2021 15:02:42 -0000 The branch stable/13 has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=8837e9c54072679b69ae0c0345e7ef7d241255aa commit 8837e9c54072679b69ae0c0345e7ef7d241255aa Author: Mitchell Horne AuthorDate: 2021-02-09 18:29:38 +0000 Commit: Mitchell Horne CommitDate: 2021-02-24 14:57:04 +0000 arm64: validate breakpoint registers In particular, we want to disallow setting breakpoints on kernel addresses from userspace. The control register fields are validated or ignored as appropriate. Reviewed by: markj Sponsored by: The FreeBSD Foundation (cherry picked from commit de2b9422807586d376ec7ffa7b660cd492464bdf) --- sys/arm64/arm64/machdep.c | 37 +++++++++++++++++++++++++++++++++---- sys/arm64/include/armreg.h | 17 +++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index 90fc19d57415..bf44dba19482 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -357,6 +357,8 @@ int set_dbregs(struct thread *td, struct dbreg *regs) { struct debug_monitor_state *monitor; + uint64_t addr; + uint32_t ctrl; int count; int i; @@ -364,11 +366,38 @@ set_dbregs(struct thread *td, struct dbreg *regs) count = 0; monitor->dbg_enable_count = 0; for (i = 0; i < DBG_BRP_MAX; i++) { - /* TODO: Check these values */ - monitor->dbg_bvr[i] = regs->db_regs[i].dbr_addr; - monitor->dbg_bcr[i] = regs->db_regs[i].dbr_ctrl; - if ((monitor->dbg_bcr[i] & 1) != 0) + addr = regs->db_regs[i].dbr_addr; + ctrl = regs->db_regs[i].dbr_ctrl; + + /* Don't let the user set a breakpoint on a kernel address. */ + if (addr >= VM_MAXUSER_ADDRESS) + return (EINVAL); + + /* + * The lowest 2 bits are ignored, so record the effective + * address. + */ + addr = rounddown2(addr, 4); + + /* + * Some control fields are ignored, and other bits reserved. + * Only unlinked, address-matching breakpoints are supported. + * + * XXX: fields that appear unvalidated, such as BAS, have + * constrained undefined behaviour. If the user mis-programs + * these, there is no risk to the system. + */ + ctrl &= DBG_BCR_EN | DBG_BCR_PMC | DBG_BCR_BAS; + if ((ctrl & DBG_BCR_EN) != 0) { + /* Only target EL0. */ + if ((ctrl & DBG_BCR_PMC) != DBG_BCR_PMC_EL0) + return (EINVAL); + monitor->dbg_enable_count++; + } + + monitor->dbg_bvr[i] = addr; + monitor->dbg_bcr[i] = ctrl; } if (monitor->dbg_enable_count > 0) monitor->dbg_flags |= DBGMON_ENABLED; diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index 201d7559320b..73d1010057b9 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -943,6 +943,23 @@ #define DBG_MDSCR_KDE (0x1 << 13) #define DBG_MDSCR_MDE (0x1 << 15) +/* Debug Breakpoint Control Registers */ +#define DBG_BCR_EN 0x1 +#define DBG_BCR_PMC_SHIFT 1 +#define DBG_BCR_PMC (0x3 << DBG_BCR_PMC_SHIFT) +#define DBG_BCR_PMC_EL1 (0x1 << DBG_BCR_PMC_SHIFT) +#define DBG_BCR_PMC_EL0 (0x2 << DBG_BCR_PMC_SHIFT) +#define DBG_BCR_BAS_SHIFT 5 +#define DBG_BCR_BAS (0xf << DBG_BCR_BAS_SHIFT) +#define DBG_BCR_HMC_SHIFT 13 +#define DBG_BCR_HMC (0x1 << DBG_BCR_HMC_SHIFT) +#define DBG_BCR_SSC_SHIFT 14 +#define DBG_BCR_SSC (0x3 << DBG_BCR_SSC_SHIFT) +#define DBG_BCR_LBN_SHIFT 16 +#define DBG_BCR_LBN (0xf << DBG_BCR_LBN_SHIFT) +#define DBG_BCR_BT_SHIFT 20 +#define DBG_BCR_BT (0xf << DBG_BCR_BT_SHIFT) + /* Perfomance Monitoring Counters */ #define PMCR_E (1 << 0) /* Enable all counters */ #define PMCR_P (1 << 1) /* Reset all counters */