Jan Kara 145407e54f select: Fix indefinitely sleeping task in poll_schedule_timeout()
commit 68514dacf2715d11b91ca50d88de047c086fea9c upstream.

A task can end up indefinitely sleeping in do_select() ->
poll_schedule_timeout() when the following race happens:

  TASK1 (thread1)             TASK2                   TASK1 (thread2)
  do_select()
    setup poll_wqueues table
    with 'fd'
                              write data to 'fd'
                                pollwake()
                                  table->triggered = 1
                                                      closes 'fd' thread1 is
                                                        waiting for
    poll_schedule_timeout()
      - sees table->triggered
      table->triggered = 0
      return -EINTR
    loop back in do_select()

But at this point when TASK1 loops back, the fdget() in the setup of
poll_wqueues fails.  So now so we never find 'fd' is ready for reading
and sleep in poll_schedule_timeout() indefinitely.

Treat an fd that got closed as a fd on which some event happened.  This
makes sure cannot block indefinitely in do_select().

Another option would be to return -EBADF in this case but that has a
potential of subtly breaking applications that excercise this behavior
and it happens to work for them.  So returning fd as active seems like a
safer choice.

Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
CC: stable@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-01-29 10:58:25 +01:00
..
2021-12-22 09:32:45 +01:00
2021-08-19 09:02:55 +09:00
2021-09-02 12:32:12 -07:00
2021-08-26 22:28:02 +02:00
2021-11-18 19:16:48 +01:00
2021-09-22 09:21:02 -07:00
2021-12-29 12:28:59 +01:00
2021-12-29 12:28:38 +01:00
2021-09-10 09:46:48 -07:00
2021-06-29 10:53:48 -07:00
2021-09-03 15:33:47 -07:00
2021-08-16 10:50:32 -06:00
2021-08-19 09:02:55 +09:00
2021-12-22 09:32:48 +01:00
2021-11-25 09:48:46 +01:00
2021-08-31 11:13:35 -07:00
2021-09-09 13:25:49 -07:00
2021-11-25 09:49:08 +01:00
2021-08-31 11:06:32 -07:00
2021-06-29 10:53:48 -07:00
2021-08-18 22:08:24 +02:00
2021-12-14 10:57:15 +01:00
2021-08-10 17:57:22 +02:00