git: 47728575b40b - releng/15.0 - posixshm: Disallow truncation of largepage objects
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 30 Jun 2026 17:21:30 UTC
The branch releng/15.0 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=47728575b40b09cf4f3b45f1fc9e89e1db8ead59
commit 47728575b40b09cf4f3b45f1fc9e89e1db8ead59
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-06-23 22:47:02 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-06-30 02:32:57 +0000
posixshm: Disallow truncation of largepage objects
We correctly handled ftruncate(), but not open(O_TRUNC).
Add a regression test.
Approved by: so
Security: FreeBSD-SA-26:44.posixshm
Security: CVE-2026-49428
Reported by: Chris Jarrett-Davies <chrisjd@openai.com>
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57831
---
sys/kern/uipc_shm.c | 8 +++-----
tests/sys/posixshm/posixshm_test.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 136bb03246f8..8ab03b5bff32 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -788,7 +788,7 @@ shm_dotruncate_largepage(struct shmfd *shmfd, off_t length, void *rl_cookie)
vm_pindex_t oldobjsz __unused;
int aflags, error, i, psind, try;
- KASSERT(length >= 0, ("shm_dotruncate: length < 0"));
+ KASSERT(length >= 0, ("shm_dotruncate_largepage: length < 0"));
object = shmfd->shm_object;
VM_OBJECT_ASSERT_WLOCKED(object);
rangelock_cookie_assert(rl_cookie, RA_WLOCKED);
@@ -1328,15 +1328,13 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
if (error == 0 &&
(flags & (O_ACCMODE | O_TRUNC)) ==
(O_RDWR | O_TRUNC)) {
- VM_OBJECT_WLOCK(shmfd->shm_object);
#ifdef MAC
error = mac_posixshm_check_truncate(
- td->td_ucred, fp->f_cred, shmfd);
+ td->td_ucred, fp->f_cred, shmfd);
if (error == 0)
#endif
- error = shm_dotruncate_locked(shmfd, 0,
+ error = shm_dotruncate_cookie(shmfd, 0,
rl_cookie);
- VM_OBJECT_WUNLOCK(shmfd->shm_object);
}
if (error == 0) {
/*
diff --git a/tests/sys/posixshm/posixshm_test.c b/tests/sys/posixshm/posixshm_test.c
index d53e8f57b89e..fbd15f079896 100644
--- a/tests/sys/posixshm/posixshm_test.c
+++ b/tests/sys/posixshm/posixshm_test.c
@@ -2150,6 +2150,43 @@ ATF_TC_BODY(largepage_reopen, tc)
"close failed; errno=%d", errno);
}
+ATF_TC_WITHOUT_HEAD(largepage_truncate);
+ATF_TC_BODY(largepage_truncate, tc)
+{
+ size_t ps[MAXPAGESIZES];
+ int fd, psind;
+
+ (void)pagesizes(ps);
+ psind = 1;
+
+ gen_test_path();
+ fd = shm_create_largepage(test_path, O_CREAT | O_RDWR, psind,
+ SHM_LARGEPAGE_ALLOC_DEFAULT, 0600);
+ if (fd < 0 && errno == ENOTTY)
+ atf_tc_skip("no large page support");
+ ATF_REQUIRE_MSG(fd >= 0, "shm_create_largepage failed; error=%d", errno);
+
+ ATF_REQUIRE_MSG(ftruncate(fd, ps[psind]) == 0,
+ "ftruncate failed; error=%d", errno);
+
+ ATF_REQUIRE_MSG(close(fd) == 0, "close failed; error=%d", errno);
+
+ fd = shm_open(test_path, O_RDWR | O_TRUNC, 0);
+ ATF_REQUIRE_MSG(fd == -1, "shm_open(O_TRUNC) should have failed");
+ ATF_REQUIRE_ERRNO(ENOTSUP, fd == -1);
+
+ fd = shm_open(test_path, O_RDWR, 0);
+ ATF_REQUIRE_MSG(fd >= 0, "shm_open failed; error=%d", errno);
+
+ ATF_REQUIRE_MSG(ftruncate(fd, ps[psind]) == 0,
+ "ftruncate to same size failed; error=%d", errno);
+
+ ATF_REQUIRE_MSG(shm_unlink(test_path) == 0,
+ "shm_unlink failed; errno=%d", errno);
+ ATF_REQUIRE_MSG(close(fd) == 0,
+ "close failed; errno=%d", errno);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, remap_object);
@@ -2201,6 +2238,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, largepage_pkru);
#endif
ATF_TP_ADD_TC(tp, largepage_reopen);
+ ATF_TP_ADD_TC(tp, largepage_truncate);
return (atf_no_error());
}