Lock the socket in soo_stat().

Otherwise nothing synchronizes with a concurrent conversion of the
socket to a listening socket.

Only the PF_LOCAL protocols implement pru_sense, and it is safe to hold
the socket lock there, so do so for now.

Reported by:	syzbot+4801f1b79ea40953ca8e@syzkaller.appspotmail.com
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Mark Johnston 2020-03-20 20:09:00 +00:00
parent 733983be9b
commit 99258935eb

View File

@ -287,9 +287,7 @@ soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred,
struct thread *td)
{
struct socket *so = fp->f_data;
#ifdef MAC
int error;
#endif
bzero((caddr_t)ub, sizeof (*ub));
ub->st_mode = S_IFSOCK;
@ -298,6 +296,7 @@ soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred,
if (error)
return (error);
#endif
SOCK_LOCK(so);
if (!SOLISTENING(so)) {
struct sockbuf *sb;
@ -320,7 +319,9 @@ soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred,
}
ub->st_uid = so->so_cred->cr_uid;
ub->st_gid = so->so_cred->cr_gid;
return (*so->so_proto->pr_usrreqs->pru_sense)(so, ub);
error = so->so_proto->pr_usrreqs->pru_sense(so, ub);
SOCK_UNLOCK(so);
return (error);
}
/*