diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2020-11-17 14:45:43 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2020-11-17 14:45:43 +0000 |
commit | 5467e46d9effc89cfce82e364261ddb6e3bd10c9 (patch) | |
tree | 028d8871399ed0d0eb696e24e4fd0e7b6a93dbf7 /sys/kern/uipc_socket.c | |
parent | a04169d3074c30bc8b447c0a1d429c459856ce9a (diff) |
Fix handling of MSG_PEEK in soreceive() for the case where an empty
mbuf is encountered in a seqpacket socket.
This diff uses the fact that setting orig_resid to 0 results in soreceive()
to return instead of looping back with the intent to sleep for more data.
orig_resid is now always set to 0 in the control message case (instead of
only if controlp is defined). This is the same behaviour as for the PR_NAME
case. Additionally orig_resid is set to 0 in the data reader when MSG_PEEK
is used.
Tested in snaps for a while and by anton@
Reported-by: syzbot+4b0e9698b344b0028b14@syzkaller.appspotmail.com
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r-- | sys/kern/uipc_socket.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 227e1ded9ca..0a47b4e8daa 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.249 2020/09/29 11:48:54 claudio Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.250 2020/11/17 14:45:42 claudio Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -892,10 +892,9 @@ dontblock: nextrecord = so->so_rcv.sb_mb->m_nextpkt; else nextrecord = so->so_rcv.sb_mb; - if (controlp && !skip) { - orig_resid = 0; + if (controlp && !skip) controlp = &(*controlp)->m_next; - } + orig_resid = 0; } /* If m is non-NULL, we have some data to read. */ @@ -963,6 +962,7 @@ dontblock: if (flags & MSG_PEEK) { m = m->m_next; moff = 0; + orig_resid = 0; } else { nextrecord = m->m_nextpkt; sbfree(&so->so_rcv, m); @@ -992,9 +992,10 @@ dontblock: SBLASTMBUFCHK(&so->so_rcv, "soreceive 3"); } } else { - if (flags & MSG_PEEK) + if (flags & MSG_PEEK) { moff += len; - else { + orig_resid = 0; + } else { if (mp) *mp = m_copym(m, 0, len, M_WAIT); m->m_data += len; |