The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=1491dec424e72a2f429d84d11b0d248abc6c6cda

commit 1491dec424e72a2f429d84d11b0d248abc6c6cda
Author:     Mark Johnston <[email protected]>
AuthorDate: 2026-06-23 22:47:02 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2026-06-30 17:00:23 +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 <[email protected]>
    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 d965576ecd9c..b1b6a8657d69 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -786,7 +786,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);
@@ -1334,15 +1334,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 6729c33a789d..e816e2d1efa7 100644
--- a/tests/sys/posixshm/posixshm_test.c
+++ b/tests/sys/posixshm/posixshm_test.c
@@ -2148,6 +2148,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, true);
+       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);
@@ -2199,6 +2236,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());
 }

Reply via email to