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);