From nobody Wed Dec 04 18:35:17 2024 X-Original-To: dev-commits-src-main@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 4Y3R5x1lFLz5g1M2; Wed, 04 Dec 2024 18:35:17 +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 "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Y3R5x1GXhz4vHt; Wed, 4 Dec 2024 18:35:17 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1733337317; 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=vWJKbNm5n5KDlgK6wPohhCp8F6hN0R3SsP+oZifwhn0=; b=dxPFjIvfvktkGAl6GaL5A+kBQ65YxXvsQB2TxGgagni1VesSnqsQG/qAyDGq9umEv9l09N SuDv9WYKx6lw3pqMeOuNTrBFFXM6s6CBaM3tB+diCGl/kPu3DSwWvOopM2zSWavfFwIoU3 D1hbGZNcfNKknovRcHNTtIIhq9+aTnnIdDhsBhwczeK0rYFaIyc5n2CvWSgzApiXHBshEJ UxRVFUo++BdKylgDncS0b1Cc5H5EsWcOZ6yeTBoffpZZIdjXTWg1s+NfzB0l9VcNHYCXzK BfvhwF7ift0maVjkMg5Ku/068FE5YtP2UwJYY1UDGaKAoTEDUBYT9pbM2CsuTQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1733337317; 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=vWJKbNm5n5KDlgK6wPohhCp8F6hN0R3SsP+oZifwhn0=; b=p0k44W+WlkUEam1JGe9b4a4wDS8lbOpAKFu9v/BocfF0EI/alC0BQRrQFhb+yLbVgjN43F 1CQjQShBmFc0mWuj411S1mfzll7uJLu1VS9RIXEBtHJKbVzxkfRdqgLtYW1vnzyDEattYM adqSS/0HSHfN9JH9S+V7qB6E9TrktjNA0cwhAnJAZrieZgSaRFllB4BybH+DxNl9Y6/MT5 CoyoT1HMlUKSPjj7BG2L/4/P1TKXDAdYp65QqlRrsK+HP7gucU/LUc9AIAInlO7cHj9Q41 sjO6o0QbdnsN76bAGz1fe/O9hWV6Sm+FFHwEwFPwTdaYGnONyQ5I6I/XLPDorg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1733337317; a=rsa-sha256; cv=none; b=tthTse6nI37xKg3gFWOneHNlQBGWJI0MI26i/Nf/ta0sJvPRhRDp7dZZ8hQCGUgrREuJrL WxR/Ky3vok8CNknbOvtHB0ldveVUm85s2RMlyMBYqXEdNHgYy9KKmISjyZAI0aXgrnp5Vs MrZBOY1cYU1yGZCbrh5DzsKw/SEkzBnNEOLQ1Fjbb4blA6lhaaX1jrFQ9e0tK7MYkSQUnL BTAgs8yMhaFioh9qR3GUHzqhTJHPwdoUqGW/tN3EtqVKUuxGASqys6rhD4F0zL2A2SOBhF YRwz1kl2LMlF2+1rpbA29TYvTK4qWSfyLBurj60zdsVJ46CVY5LirPG3VQFvfA== 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 4Y3R5x0smLzJK0; Wed, 4 Dec 2024 18:35:17 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 4B4IZHYq077993; Wed, 4 Dec 2024 18:35:17 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4B4IZHbL077990; Wed, 4 Dec 2024 18:35:17 GMT (envelope-from git) Date: Wed, 4 Dec 2024 18:35:17 GMT Message-Id: <202412041835.4B4IZHbL077990@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: f3b7dbdad53b - main - shm: Handle swap pager allocation failures List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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/main X-Git-Reftype: branch X-Git-Commit: f3b7dbdad53b31492757417fc1336ed74ec80fd8 Auto-Submitted: auto-generated The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=f3b7dbdad53b31492757417fc1336ed74ec80fd8 commit f3b7dbdad53b31492757417fc1336ed74ec80fd8 Author: Mark Johnston AuthorDate: 2024-12-04 01:04:33 +0000 Commit: Mark Johnston CommitDate: 2024-12-04 16:22:50 +0000 shm: Handle swap pager allocation failures shm_alloc() can fail if swap reservation fails (i.e., vm.overcommit is non-zero) or racct is imposing some limits on swap usage. PR: 282994 MFC after: 2 weeks Reviewed by: olce, kib Differential Revision: https://reviews.freebsd.org/D47839 --- sys/kern/kern_umtx.c | 8 +++++- sys/kern/uipc_shm.c | 80 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index b71fa9a6de24..c4a820f41bc3 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -4485,6 +4485,7 @@ static int umtx_shm_create_reg(struct thread *td, const struct umtx_key *key, struct umtx_shm_reg **res) { + struct shmfd *shm; struct umtx_shm_reg *reg, *reg1; struct ucred *cred; int error; @@ -4504,9 +4505,14 @@ umtx_shm_create_reg(struct thread *td, const struct umtx_key *key, cred = td->td_ucred; if (!chgumtxcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_UMTXP))) return (ENOMEM); + shm = shm_alloc(td->td_ucred, O_RDWR, false); + if (shm == NULL) { + chgumtxcnt(cred->cr_ruidinfo, -1, 0); + return (ENOMEM); + } reg = uma_zalloc(umtx_shm_reg_zone, M_WAITOK | M_ZERO); bcopy(key, ®->ushm_key, sizeof(*key)); - reg->ushm_obj = shm_alloc(td->td_ucred, O_RDWR, false); + reg->ushm_obj = shm; reg->ushm_cred = crhold(cred); error = shm_dotruncate(reg->ushm_obj, PAGE_SIZE); if (error != 0) { diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c index 074ca514c77d..026611a59593 100644 --- a/sys/kern/uipc_shm.c +++ b/sys/kern/uipc_shm.c @@ -939,22 +939,32 @@ shm_alloc(struct ucred *ucred, mode_t mode, bool largepage) struct shmfd *shmfd; vm_object_t obj; + if (largepage) { + obj = phys_pager_allocate(NULL, &shm_largepage_phys_ops, + NULL, 0, VM_PROT_DEFAULT, 0, ucred); + } else { + obj = vm_pager_allocate(shmfd_pager_type, NULL, 0, + VM_PROT_DEFAULT, 0, ucred); + } + if (obj == NULL) { + /* + * swap reservation limits can cause object allocation + * to fail. + */ + return (NULL); + } + shmfd = malloc(sizeof(*shmfd), M_SHMFD, M_WAITOK | M_ZERO); - shmfd->shm_size = 0; shmfd->shm_uid = ucred->cr_uid; shmfd->shm_gid = ucred->cr_gid; shmfd->shm_mode = mode; if (largepage) { - obj = phys_pager_allocate(NULL, &shm_largepage_phys_ops, - NULL, shmfd->shm_size, VM_PROT_DEFAULT, 0, ucred); obj->un_pager.phys.phys_priv = shmfd; shmfd->shm_lp_alloc_policy = SHM_LARGEPAGE_ALLOC_DEFAULT; } else { - obj = vm_pager_allocate(shmfd_pager_type, NULL, - shmfd->shm_size, VM_PROT_DEFAULT, 0, ucred); obj->un_pager.swp.swp_priv = shmfd; } - KASSERT(obj != NULL, ("shm_create: vm_pager_allocate")); + VM_OBJECT_WLOCK(obj); vm_object_set_flag(obj, OBJ_POSIXSHM); VM_OBJECT_WUNLOCK(obj); @@ -1211,8 +1221,8 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode, if (CAP_TRACING(td)) ktrcapfail(CAPFAIL_NAMEI, path); if (IN_CAPABILITY_MODE(td)) { - free(path, M_SHMFD); - return (ECAPMODE); + error = ECAPMODE; + goto outnofp; } #endif @@ -1232,20 +1242,21 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode, * in sys_shm_open() to keep this implementation compliant. */ error = falloc_caps(td, &fp, &fd, flags & O_CLOEXEC, fcaps); - if (error) { - free(path, M_SHMFD); - return (error); - } + if (error != 0) + goto outnofp; /* A SHM_ANON path pointer creates an anonymous object. */ if (userpath == SHM_ANON) { /* A read-only anonymous object is pointless. */ if ((flags & O_ACCMODE) == O_RDONLY) { - fdclose(td, fp, fd); - fdrop(fp, td); - return (EINVAL); + error = EINVAL; + goto out; } shmfd = shm_alloc(td->td_ucred, cmode, largepage); + if (shmfd == NULL) { + error = ENOMEM; + goto out; + } shmfd->shm_seals = initial_seals; shmfd->shm_flags = shmflags; } else { @@ -1262,17 +1273,26 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode, #endif shmfd = shm_alloc(td->td_ucred, cmode, largepage); - shmfd->shm_seals = initial_seals; - shmfd->shm_flags = shmflags; - shm_insert(path, fnv, shmfd); + if (shmfd == NULL) { + error = ENOMEM; + } else { + shmfd->shm_seals = + initial_seals; + shmfd->shm_flags = shmflags; + shm_insert(path, fnv, shmfd); + path = NULL; + } #ifdef MAC } #endif } else { - free(path, M_SHMFD); error = ENOENT; } } else { + /* + * Object already exists, obtain a new reference if + * requested and permitted. + */ rl_cookie = shm_rangelock_wlock(shmfd, 0, OFF_MAX); /* @@ -1285,12 +1305,6 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode, */ initial_seals &= ~shmfd->shm_seals; - /* - * Object already exists, obtain a new - * reference if requested and permitted. - */ - free(path, M_SHMFD); - /* * initial_seals can't set additional seals if we've * already been set F_SEAL_SEAL. If F_SEAL_SEAL is set, @@ -1349,19 +1363,25 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode, } sx_xunlock(&shm_dict_lock); - if (error) { - fdclose(td, fp, fd); - fdrop(fp, td); - return (error); - } + if (error != 0) + goto out; } finit(fp, FFLAGS(flags & O_ACCMODE), DTYPE_SHM, shmfd, &shm_ops); td->td_retval[0] = fd; fdrop(fp, td); + free(path, M_SHMFD); return (0); + +out: + fdclose(td, fp, fd); + fdrop(fp, td); +outnofp: + free(path, M_SHMFD); + + return (error); } /* System calls. */