The ioctl of socket fd should return -1 after listen to avoid misusing. ``` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0.1 ioctl(3, SIOCINQ, [0]) = 0 +0 bind(3, ..., ...) = 0 +0.1 ioctl(3, SIOCINQ, [0]) = 0 +0 listen(3, 1) = 0 +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> +0 ~ +1 > S. 0:0(0) ack 1 <...> +.1 < . 1:1(0) ack 1 win 32792 +0.1 accept(3, ..., ...) = 4 +0 < . 1:41(40) ack 1 win 28273 +0.1 ioctl(4, FIONREAD, [40]) = 0 +0.1 ioctl(3, FIONREAD, [0]) = -1 // f-stack/FreeBSD return 0 here ```
Sorry, the script should be ``` 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0.1 ioctl(3, FIONREAD, [0]) = 0 +0 bind(3, ..., ...) = 0 +0.1 ioctl(3, FIONREAD, [0]) = 0 +0 listen(3, 1) = 0 +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> +0 ~ +1 > S. 0:0(0) ack 1 <...> +.1 < . 1:1(0) ack 1 win 32792 +0.1 accept(3, ..., ...) = 4 +0 < . 1:41(40) ack 1 win 28273 +0.1 ioctl(4, FIONREAD, [40]) = 0 +0.1 ioctl(3, FIONREAD, [0]) = -1 ``` No SIOCINQ in FreeBSD.
A fix is under review D26897. Avoiding accessing the send and receive buffers is necessary. Instead of returning an error, one could return 0 in all cases. Right now, I prefer to return an error. Let's see how the discussion of the review goes...
A commit references this bug: Author: tuexen Date: Sat Nov 7 21:17:49 UTC 2020 New revision: 367464 URL: https://svnweb.freebsd.org/changeset/base/367464 Log: The ioctl() calls using FIONREAD, FIONWRITE, FIONSPACE, and SIOCATMARK access the socket send or receive buffer. This is not possible for listening sockets since r319722. Because send()/recv() calls fail on listening sockets, fail also ioctl() indicating EINVAL. PR: 250366 Reported by: Yong-Hao Zou Reviewed by: glebius, rscheff MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D26897 Changes: head/sys/kern/sys_socket.c
A commit references this bug: Author: tuexen Date: Mon Nov 30 09:21:02 UTC 2020 New revision: 368179 URL: https://svnweb.freebsd.org/changeset/base/368179 Log: MFC r367464: The ioctl() calls using FIONREAD, FIONWRITE, FIONSPACE, and SIOCATMARK access the socket send or receive buffer. This is not possible for listening sockets since r319722. Because send()/recv() calls fail on listening sockets, fail also ioctl() indicating EINVAL. PR: 250366 Reported by: Yong-Hao Zou Reviewed by: glebius, rscheff Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D26897 Changes: _U stable/12/ stable/12/sys/kern/sys_socket.c