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:
parent
733983be9b
commit
99258935eb
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user