mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
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
This commit is contained in:
1 parent
1c49551def
commit
9c06b54ab6
2 files changed
+41
-5
No files matched your search
+3
-5
@@ -824,7 +824,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);
|
||||
@@ -1345,15 +1345,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) {
|
||||
/*
|
||||
|
||||
@@ -2151,6 +2151,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);
|
||||
@@ -2202,6 +2239,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());
|
||||
}
|
||||
Reference in new issue
Block a user