aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2026-06-24 19:56:07 +0000
committerMark Johnston <markj@FreeBSD.org>2026-06-30 17:00:23 +0000
commit713747f87c85e9b961e460cb9a496c094a6aa375 (patch)
tree846fed98a543b9f5f386a2e39b259d03bb16a102
parenteec9084656bcd7dd52f8f564c96dc6aced5be554 (diff)
posixshm: Disallow fspacectl() on largepage objects
As with truncation, the operation isn't supported, but nothing prevented it. 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/D57830
-rw-r--r--sys/kern/uipc_shm.c5
-rw-r--r--tests/sys/posixshm/posixshm_test.c22
2 files changed, 26 insertions, 1 deletions
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 197409d97f0c..d965576ecd9c 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -2096,11 +2096,14 @@ shm_fspacectl(struct file *fp, int cmd, off_t *offset, off_t *length, int flags,
("shm_fspacectl: non-zero flags"));
KASSERT(*offset >= 0 && *length > 0 && *length <= OFF_MAX - *offset,
("shm_fspacectl: offset/length overflow or underflow"));
- error = EINVAL;
+
shmfd = fp->f_data;
off = *offset;
len = *length;
+ if (shm_largepage(shmfd))
+ return (ENOTSUP);
+
rl_cookie = shm_rangelock_wlock(shmfd, off, off + len);
switch (cmd) {
case SPACECTL_DEALLOC:
diff --git a/tests/sys/posixshm/posixshm_test.c b/tests/sys/posixshm/posixshm_test.c
index fe6386c6aa4b..6729c33a789d 100644
--- a/tests/sys/posixshm/posixshm_test.c
+++ b/tests/sys/posixshm/posixshm_test.c
@@ -1369,6 +1369,27 @@ ATF_TC_BODY(largepage_config, tc)
ATF_REQUIRE(close(fd) == 0);
}
+ATF_TC_WITHOUT_HEAD(largepage_fspacectl);
+ATF_TC_BODY(largepage_fspacectl, tc)
+{
+ struct spacectl_range range;
+ size_t ps[MAXPAGESIZES];
+ int fd, pscnt;
+
+ pscnt = pagesizes(ps, true);
+
+ for (int i = 1; i < pscnt; i++) {
+ fd = shm_open_large(i, SHM_LARGEPAGE_ALLOC_DEFAULT, ps[i]);
+
+ range.r_offset = 0;
+ range.r_len = ps[i];
+ ATF_REQUIRE_ERRNO(ENOTSUP,
+ fspacectl(fd, SPACECTL_DEALLOC, &range, 0, &range) == -1);
+
+ ATF_REQUIRE(close(fd) == 0);
+ }
+}
+
ATF_TC_WITHOUT_HEAD(largepage_mmap);
ATF_TC_BODY(largepage_mmap, tc)
{
@@ -2165,6 +2186,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, mmap_prot);
ATF_TP_ADD_TC(tp, largepage_basic);
ATF_TP_ADD_TC(tp, largepage_config);
+ ATF_TP_ADD_TC(tp, largepage_fspacectl);
ATF_TP_ADD_TC(tp, largepage_mmap);
ATF_TP_ADD_TC(tp, largepage_munmap);
ATF_TP_ADD_TC(tp, largepage_madvise);