Author: tuexen
Date: Sat Nov  7 21:17:49 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

Modified:
  head/sys/kern/sys_socket.c

Modified: head/sys/kern/sys_socket.c
==============================================================================
--- head/sys/kern/sys_socket.c  Sat Nov  7 19:57:19 2020        (r367463)
+++ head/sys/kern/sys_socket.c  Sat Nov  7 21:17:49 2020        (r367464)
@@ -207,21 +207,34 @@ soo_ioctl(struct file *fp, u_long cmd, void *data, str
 
        case FIONREAD:
                /* Unlocked read. */
-               *(int *)data = sbavail(&so->so_rcv);
+               if (SOLISTENING(so)) {
+                       error = EINVAL;
+               } else {
+                       *(int *)data = sbavail(&so->so_rcv);
+               }
                break;
 
        case FIONWRITE:
                /* Unlocked read. */
-               *(int *)data = sbavail(&so->so_snd);
+               if (SOLISTENING(so)) {
+                       error = EINVAL;
+               } else {
+                       *(int *)data = sbavail(&so->so_snd);
+               }
                break;
 
        case FIONSPACE:
                /* Unlocked read. */
-               if ((so->so_snd.sb_hiwat < sbused(&so->so_snd)) ||
-                   (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt))
-                       *(int *)data = 0;
-               else
-                       *(int *)data = sbspace(&so->so_snd);
+               if (SOLISTENING(so)) {
+                       error = EINVAL;
+               } else {
+                       if ((so->so_snd.sb_hiwat < sbused(&so->so_snd)) ||
+                           (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt)) {
+                               *(int *)data = 0;
+                       } else {
+                               *(int *)data = sbspace(&so->so_snd);
+                       }
+               }
                break;
 
        case FIOSETOWN:
@@ -242,7 +255,11 @@ soo_ioctl(struct file *fp, u_long cmd, void *data, str
 
        case SIOCATMARK:
                /* Unlocked read. */
-               *(int *)data = (so->so_rcv.sb_state & SBS_RCVATMARK) != 0;
+               if (SOLISTENING(so)) {
+                       error = EINVAL;
+               } else {
+                       *(int *)data = (so->so_rcv.sb_state & SBS_RCVATMARK) != 
0;
+               }
                break;
        default:
                /*
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to