diff options
author | Mark Johnston <markj@FreeBSD.org> | 2020-03-20 20:09:00 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2020-03-20 20:09:00 +0000 |
commit | 99258935eb2bbb0c8b0ec77c632d7f90a4f6642c (patch) | |
tree | 1d8022ca3c798fef78777f86164195cb2c3c2f51 /sys | |
parent | 733983be9b68587463e04fb774b31f5a501a010b (diff) | |
download | src-99258935eb2bbb0c8b0ec77c632d7f90a4f6642c.tar.gz src-99258935eb2bbb0c8b0ec77c632d7f90a4f6642c.zip |
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
Notes
Notes:
svn path=/head/; revision=359184
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/sys_socket.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index 2eeda8e51a4e..37ce4f17e911 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -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); } /* |