Date: Sat, 29 Jun 2019 16:11:09 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r349547 - head/sys/kern Message-ID: <201906291611.x5TGB908022248@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Sat Jun 29 16:11:09 2019 New Revision: 349547 URL: https://svnweb.freebsd.org/changeset/base/349547 Log: Use a consistent snapshot of the fd's rights in fget_mmap(). fget_mmap() translates rights on the descriptor to a VM protection mask. It was doing so without holding any locks on the descriptor table, so a writer could simultaneously be modifying those rights. Such a situation would be detected using a sequence counter, but not before an inconsistency could trigger assertion failures in the capability code. Fix the problem by copying the fd's rights to a structure on the stack, and perform the translation only once we know that that snapshot is consistent. Reported by: syzbot+ae359438769fda1840f8@syzkaller.appspotmail.com Reviewed by: brooks, mjg MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D20800 Modified: head/sys/kern/kern_descrip.c Modified: head/sys/kern/kern_descrip.c ============================================================================== --- head/sys/kern/kern_descrip.c Sat Jun 29 16:05:52 2019 (r349546) +++ head/sys/kern/kern_descrip.c Sat Jun 29 16:11:09 2019 (r349547) @@ -2761,6 +2761,7 @@ fget_mmap(struct thread *td, int fd, cap_rights_t *rig if (maxprotp != NULL) *maxprotp = VM_PROT_ALL; #else + cap_rights_t fdrights; struct filedesc *fdp = td->td_proc->p_fd; seqc_t seq; @@ -2769,15 +2770,18 @@ fget_mmap(struct thread *td, int fd, cap_rights_t *rig error = _fget(td, fd, fpp, 0, rightsp, &seq); if (error != 0) return (error); - /* - * If requested, convert capability rights to access flags. - */ if (maxprotp != NULL) - *maxprotp = cap_rights_to_vmprot(cap_rights(fdp, fd)); + fdrights = *cap_rights(fdp, fd); if (!fd_modified(fdp, fd, seq)) break; fdrop(*fpp, td); } + + /* + * If requested, convert capability rights to access flags. + */ + if (maxprotp != NULL) + *maxprotp = cap_rights_to_vmprot(&fdrights); #endif return (error); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201906291611.x5TGB908022248>