select: Fix indefinitely sleeping task in poll_schedule_timeout()
stable inclusion from stable-v5.10.95 commit 11ba2c6dfb902de05b73000a98534e376173b6ca bugzilla: https://gitee.com/openeuler/kernel/issues/I55EDV Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=11ba2c6dfb902de05b73000a98534e376173b6ca -------------------------------- commit 68514dac 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> Signed-off-by:
Yu Liao <liaoyu15@huawei.com> Reviewed-by:
Wei Li <liwei391@huawei.com> Signed-off-by:
Zheng Zengkai <zhengzengkai@huawei.com>
Loading
Please sign in to comment