From nobody Wed Dec 17 14:08:55 2025 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 4dWbJ73t86z6L9yS for ; Wed, 17 Dec 2025 14:08: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 "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4dWbJ720PHz3Jbx for ; Wed, 17 Dec 2025 14:08:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1765980535; 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=+YksOnLJjcmpnO3XqDPMYarodCXVfDVg81njEczNpPA=; b=ffRbcnrC73BVOmvCxoyAjWOkZ2MyoTBAuOGfZ68GjhGRWAoBSEJe6BRAByXWtvmT73h0rL koZxjnMMMGa+Pfv+BAg5J26c+QvmLLFVTUszXrE5afENyGP7Nb0hl8eIM94fY/qYPNsMns HeUQQ5eiJwQECLs9tZrDAQ4Xa+S2Fr1j1W8+TmZHaqXjYI9jOg/RJgrzJxlG5ognF7+6ut 4wzOwT7L6uT/BjSptPauwtv1iAL2EW6fals3yK0NdMa8jSEZ+sJyftgZkS7+3S1lJ+TXmZ MBSX5X/HbJHDDcG/NNtH+iK1Jloojolljpq2nzrnYVymuTdvkm7noyLm2doHEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1765980535; 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=+YksOnLJjcmpnO3XqDPMYarodCXVfDVg81njEczNpPA=; b=FzNiNtvFDE62sJyTA5l3lawv0SclGwECdGaomzE53WsDRhNz6NUM4ge3DQcSMkMEMDyvju DdvZE6nircP0jN7IGUFiel32bTnn5lMd1zjxVGZPl51GtUBXwh0EGgyXacxuBtE1oYDK6J 8zoUpuAvQlHYcJ2pnzvOsT+iE+0/uuE/GfOk2XaDPD01eXKI87Wp3SWbGUUNCLARNXQz+A aOmYak+6H87cWE78jQ1oK8RaCndZgaIptPTMVw2UwBql9j3c72VLDO0un6qqvT0060nxsC bxiJlGQZ6Sq4K/WY5bkhSfAHXufqOVvqS4c/IhOLi4DugsV8vd3QAzA4T8pekA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1765980535; a=rsa-sha256; cv=none; b=jDa3LwvUJZq50YCzaLjUN2CB7T3eNX58Hap7OAjb8/BdnM96bQs1ID3n8IaCyK0pVAzv+S dp7tlKGJ3UAqfC6XatJygoV6CvFdhNLAKo+DFj28QsUEu+snkg/6Rp+yMP0v82wSQUicHo F/qLdlsAr7tzJ0Z09tp3SuyJxCNe3CtjXDhuw0oK2v7HUwZhN9a+F94WHGYtJxQo5d4CwJ LRk1HxgNyWbJB1mK7tzxxn0ZxRcJLCELUzV8CWpVTpTJ9hIrUrJijed+ThcIz3K3DvKP9i 4Xg2/ZjSwyCq62vLc9jnMvVEzwTM982F5f6z+nph2T6IezI5P5Y3K1tmDT2Hew== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4dWbJ70kzRzvdv for ; Wed, 17 Dec 2025 14:08:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 387dc by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 17 Dec 2025 14:08:55 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Bojan Novk=?utf-8?Q?ovi=C4=87?= Subject: git: 1092ec8b3375 - main - kern: Introduce RLIMIT_VMM 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: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bnovkov X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 1092ec8b337595ed8d52accf41c6904d75b3689d Auto-Submitted: auto-generated Date: Wed, 17 Dec 2025 14:08:55 +0000 Message-Id: <6942b977.387dc.1bc32951@gitrepo.freebsd.org> The branch main has been updated by bnovkov: URL: https://cgit.FreeBSD.org/src/commit/?id=1092ec8b337595ed8d52accf41c6904d75b3689d commit 1092ec8b337595ed8d52accf41c6904d75b3689d Author: Bojan Novković AuthorDate: 2025-11-07 13:11:03 +0000 Commit: Bojan Novković CommitDate: 2025-12-17 14:08:31 +0000 kern: Introduce RLIMIT_VMM This change introduces a new per-UID limit for controlling the number of vmm instances, in anticipation of unprivileged bhyve. This allows ut to limit the amount of kernel memory allocated by the vmm driver and prevent potential memory exhaustion attacks. Differential Revision: https://reviews.freebsd.org/D53728 Reviewed by: markj, olce, corvink MFC after: 3 months Sponsored by: The FreeBSD Foundation Sponsored by: Klara, Inc. --- sys/dev/vmm/vmm_dev.c | 18 +++++++++++++++--- sys/kern/kern_resource.c | 13 +++++++++++++ sys/sys/resource.h | 4 +++- sys/sys/resourcevar.h | 2 ++ usr.bin/procstat/procstat_rlimit.c | 1 + 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c index d6543bf6534e..3a86a8f966ef 100644 --- a/sys/dev/vmm/vmm_dev.c +++ b/sys/dev/vmm/vmm_dev.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -96,6 +97,10 @@ u_int vm_maxcpu; SYSCTL_UINT(_hw_vmm, OID_AUTO, maxcpu, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &vm_maxcpu, 0, "Maximum number of vCPUs"); +u_int vm_maxvmms; +SYSCTL_UINT(_hw_vmm, OID_AUTO, maxvmms, CTLFLAG_RWTUN, + &vm_maxvmms, 0, "Maximum number of VMM instances per user"); + static void devmem_destroy(void *arg); static int devmem_create_cdev(struct vmmdev_softc *sc, int id, char *devmem); @@ -870,6 +875,7 @@ vmmdev_destroy(struct vmmdev_softc *sc) int error __diagused; KASSERT(sc->cdev == NULL, ("%s: cdev not free", __func__)); + KASSERT(sc->ucred != NULL, ("%s: missing ucred", __func__)); /* * Destroy all cdevs: @@ -898,8 +904,8 @@ vmmdev_destroy(struct vmmdev_softc *sc) if (sc->vm != NULL) vm_destroy(sc->vm); - if (sc->ucred != NULL) - crfree(sc->ucred); + chgvmmcnt(sc->ucred->cr_ruidinfo, -1, 0); + crfree(sc->ucred); sx_xlock(&vmmdev_mtx); SLIST_REMOVE(&head, sc, vmmdev_softc, link); @@ -1021,6 +1027,12 @@ vmmdev_create(const char *name, struct ucred *cred) vmmdev_destroy(sc); return (error); } + if (!chgvmmcnt(cred->cr_ruidinfo, 1, vm_maxvmms)) { + sx_xunlock(&vmmdev_mtx); + destroy_dev(cdev); + vmmdev_destroy(sc); + return (ENOMEM); + } sc->cdev = cdev; sx_xunlock(&vmmdev_mtx); return (0); @@ -1172,7 +1184,7 @@ vmm_handler(module_t mod, int what, void *arg) } if (vm_maxcpu == 0) vm_maxcpu = 1; - + vm_maxvmms = 4 * mp_ncpus; error = vmm_modinit(); if (error == 0) vmm_initialized = true; diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index dcd38c6e6fbe..31f89bd41f6d 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -895,6 +895,9 @@ getrlimitusage_one(struct proc *p, u_int which, int flags, rlim_t *res) case RLIMIT_PIPEBUF: *res = ui->ui_pipecnt; break; + case RLIMIT_VMM: + *res = ui->ui_vmmcnt; + break; default: error = EINVAL; break; @@ -1643,6 +1646,9 @@ uifree(struct uidinfo *uip) if (uip->ui_inotifywatchcnt != 0) printf("freeing uidinfo: uid = %d, inotifywatchcnt = %ld\n", uip->ui_uid, uip->ui_inotifywatchcnt); + if (uip->ui_vmmcnt != 0) + printf("freeing vmmcnt: uid = %d, vmmcnt = %ld\n", + uip->ui_uid, uip->ui_vmmcnt); free(uip, M_UIDINFO); } @@ -1763,6 +1769,13 @@ chginotifywatchcnt(struct uidinfo *uip, int diff, rlim_t max) "inotifywatchcnt")); } +int +chgvmmcnt(struct uidinfo *uip, int diff, rlim_t max) +{ + + return (chglimit(uip, &uip->ui_vmmcnt, diff, max, "vmmcnt")); +} + static int sysctl_kern_proc_rlimit_usage(SYSCTL_HANDLER_ARGS) { diff --git a/sys/sys/resource.h b/sys/sys/resource.h index 2725aa1ef646..9e0635cdb328 100644 --- a/sys/sys/resource.h +++ b/sys/sys/resource.h @@ -115,8 +115,9 @@ struct __wrusage { #define RLIMIT_KQUEUES 13 /* kqueues allocated */ #define RLIMIT_UMTXP 14 /* process-shared umtx */ #define RLIMIT_PIPEBUF 15 /* pipes/fifos buffers */ +#define RLIMIT_VMM 16 /* virtual machines */ -#define RLIM_NLIMITS 16 /* number of resource limits */ +#define RLIM_NLIMITS 17 /* number of resource limits */ #define RLIM_INFINITY ((rlim_t)(((__uint64_t)1 << 63) - 1)) #define RLIM_SAVED_MAX RLIM_INFINITY @@ -144,6 +145,7 @@ static const char *rlimit_ident[] = { "kqueues", "umtx", "pipebuf", + "vmm", }; #endif diff --git a/sys/sys/resourcevar.h b/sys/sys/resourcevar.h index 61411890c85b..d5c4561eec66 100644 --- a/sys/sys/resourcevar.h +++ b/sys/sys/resourcevar.h @@ -124,6 +124,7 @@ struct uidinfo { long ui_pipecnt; /* (b) consumption of pipe buffers */ long ui_inotifycnt; /* (b) number of inotify descriptors */ long ui_inotifywatchcnt; /* (b) number of inotify watches */ + long ui_vmmcnt; /* (b) number of vmm instances */ uid_t ui_uid; /* (a) uid */ u_int ui_ref; /* (b) reference count */ #ifdef RACCT @@ -148,6 +149,7 @@ int chgumtxcnt(struct uidinfo *uip, int diff, rlim_t maxval); int chgpipecnt(struct uidinfo *uip, int diff, rlim_t max); int chginotifycnt(struct uidinfo *uip, int diff, rlim_t maxval); int chginotifywatchcnt(struct uidinfo *uip, int diff, rlim_t maxval); +int chgvmmcnt(struct uidinfo *uip, int diff, rlim_t max); int kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which, struct rlimit *limp); struct plimit diff --git a/usr.bin/procstat/procstat_rlimit.c b/usr.bin/procstat/procstat_rlimit.c index c34550295f05..f3132758e005 100644 --- a/usr.bin/procstat/procstat_rlimit.c +++ b/usr.bin/procstat/procstat_rlimit.c @@ -64,6 +64,7 @@ static struct { {"kqueues", " "}, {"umtxp", " "}, {"pipebuf", "B "}, + {"virtual-machines", " "}, }; _Static_assert(nitems(rlimit_param) == RLIM_NLIMITS,