Author: wulf
Date: Sun Nov 24 20:51:09 2019
New Revision: 355068
URL: https://svnweb.freebsd.org/changeset/base/355068

Log:
  Linux epoll: Allow passing of any negative timeout value to epoll_wait
  
  Linux epoll allow passing of any negative timeout value to epoll_wait()
  to cause unbound blocking
  
  Reviewed by:  emaste
  MFC after:    1 week
  Differential Revision:        https://reviews.freebsd.org/D22517

Modified:
  head/sys/compat/linux/linux_event.c

Modified: head/sys/compat/linux/linux_event.c
==============================================================================
--- head/sys/compat/linux/linux_event.c Sun Nov 24 20:47:40 2019        
(r355067)
+++ head/sys/compat/linux/linux_event.c Sun Nov 24 20:51:09 2019        
(r355068)
@@ -557,13 +557,13 @@ linux_epoll_wait_common(struct thread *td, int epfd, s
                return (error);
        if (epfp->f_type != DTYPE_KQUEUE) {
                error = EINVAL;
-               goto leave1;
+               goto leave;
        }
        if (uset != NULL) {
                error = kern_sigprocmask(td, SIG_SETMASK, uset,
                    &omask, 0);
                if (error != 0)
-                       goto leave1;
+                       goto leave;
                td->td_pflags |= TDP_OLDMASK;
                /*
                 * Make sure that ast() is called on return to
@@ -581,11 +581,12 @@ linux_epoll_wait_common(struct thread *td, int epfd, s
        coargs.count = 0;
        coargs.error = 0;
 
-       if (timeout != -1) {
-               if (timeout < 0) {
-                       error = EINVAL;
-                       goto leave0;
-               }
+       /*
+        * Linux epoll_wait(2) man page states that timeout of -1 causes caller
+        * to block indefinitely. Real implementation does it if any negative
+        * timeout value is passed.
+        */
+       if (timeout >= 0) {
                /* Convert from milliseconds to timespec. */
                ts.tv_sec = timeout / 1000;
                ts.tv_nsec = (timeout % 1000) * 1000000;
@@ -605,11 +606,10 @@ linux_epoll_wait_common(struct thread *td, int epfd, s
        if (error == 0)
                td->td_retval[0] = coargs.count;
 
-leave0:
        if (uset != NULL)
                error = kern_sigprocmask(td, SIG_SETMASK, &omask,
                    NULL, 0);
-leave1:
+leave:
        fdrop(epfp, td);
        return (error);
 }
_______________________________________________
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