git: d0ca50b414be - stable/14 - uipc_shm: Copyin userpath for ktrace(2)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 12 May 2024 00:08:34 UTC
The branch stable/14 has been updated by jfree:
URL: https://cgit.FreeBSD.org/src/commit/?id=d0ca50b414beebe5e61154541c9a2fb085df37f0
commit d0ca50b414beebe5e61154541c9a2fb085df37f0
Author: Jake Freeland <jfree@FreeBSD.org>
AuthorDate: 2024-04-10 02:17:11 +0000
Commit: Jake Freeland <jfree@FreeBSD.org>
CommitDate: 2024-05-11 23:57:44 +0000
uipc_shm: Copyin userpath for ktrace(2)
If userpath is not SHM_ANON, then copy it in early so ktrace(2) can
record it. Without this change, ktrace(2) will attempt to strcpy a
userspace string and trigger a page fault.
Reported by: syzbot+490b9c2a89f53b1b9779@syzkaller.appspotmail.com
Fixes: 0cd9cde767c3
Approved by: markj (mentor)
Reviewed by: markj
MFC after: 1 month
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D44702
(cherry picked from commit b112232e4fb931ebafae9d79fbc970e3df020b57)
---
sys/kern/uipc_shm.c | 44 +++++++++++++++++++++++---------------------
1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 613656ca0a5a..31c80913be84 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -1172,18 +1172,6 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
if ((shmflags & SHM_ALLOW_SEALING) != 0)
initial_seals &= ~F_SEAL_SEAL;
-#ifdef CAPABILITY_MODE
- /*
- * shm_open(2) is only allowed for anonymous objects.
- */
- if (userpath != SHM_ANON) {
- if (CAP_TRACING(td))
- ktrcapfail(CAPFAIL_NAMEI, userpath);
- if (IN_CAPABILITY_MODE(td))
- return (ECAPMODE);
- }
-#endif
-
AUDIT_ARG_FFLAGS(flags);
AUDIT_ARG_MODE(mode);
@@ -1208,6 +1196,26 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
if ((initial_seals & ~F_SEAL_SEAL) != 0)
return (EINVAL);
+ if (userpath != SHM_ANON) {
+ error = shm_copyin_path(td, userpath, &path);
+ if (error != 0)
+ return (error);
+
+#ifdef CAPABILITY_MODE
+ /*
+ * shm_open(2) is only allowed for anonymous objects.
+ */
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_NAMEI, path);
+ if (IN_CAPABILITY_MODE(td)) {
+ free(path, M_SHMFD);
+ return (ECAPMODE);
+ }
+#endif
+
+ AUDIT_ARG_UPATH1_CANON(path);
+ }
+
pdp = td->td_proc->p_pd;
cmode = (mode & ~pdp->pd_cmask) & ACCESSPERMS;
@@ -1219,8 +1227,10 @@ 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)
+ if (error) {
+ free(path, M_SHMFD);
return (error);
+ }
/* A SHM_ANON path pointer creates an anonymous object. */
if (userpath == SHM_ANON) {
@@ -1234,14 +1244,6 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
shmfd->shm_seals = initial_seals;
shmfd->shm_flags = shmflags;
} else {
- error = shm_copyin_path(td, userpath, &path);
- if (error != 0) {
- fdclose(td, fp, fd);
- fdrop(fp, td);
- return (error);
- }
-
- AUDIT_ARG_UPATH1_CANON(path);
fnv = fnv_32_str(path, FNV1_32_INIT);
sx_xlock(&shm_dict_lock);
shmfd = shm_lookup(path, fnv);