2017-11-01 15:08:43 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
2007-05-10 22:22:40 -07:00
|
|
|
#ifndef __ASM_GENERIC_POLL_H
|
|
|
|
#define __ASM_GENERIC_POLL_H
|
|
|
|
|
|
|
|
/* These are specified by iBCS2 */
|
2018-02-01 15:13:18 -05:00
|
|
|
#define POLLIN 0x0001
|
|
|
|
#define POLLPRI 0x0002
|
|
|
|
#define POLLOUT 0x0004
|
|
|
|
#define POLLERR 0x0008
|
|
|
|
#define POLLHUP 0x0010
|
|
|
|
#define POLLNVAL 0x0020
|
2007-05-10 22:22:40 -07:00
|
|
|
|
|
|
|
/* The rest seem to be more-or-less nonstandard. Check them! */
|
2018-02-01 15:13:18 -05:00
|
|
|
#define POLLRDNORM 0x0040
|
|
|
|
#define POLLRDBAND 0x0080
|
2007-05-10 22:22:40 -07:00
|
|
|
#ifndef POLLWRNORM
|
2018-02-01 15:13:18 -05:00
|
|
|
#define POLLWRNORM 0x0100
|
2007-05-10 22:22:40 -07:00
|
|
|
#endif
|
|
|
|
#ifndef POLLWRBAND
|
2018-02-01 15:13:18 -05:00
|
|
|
#define POLLWRBAND 0x0200
|
2007-05-10 22:22:40 -07:00
|
|
|
#endif
|
|
|
|
#ifndef POLLMSG
|
2018-02-01 15:13:18 -05:00
|
|
|
#define POLLMSG 0x0400
|
2007-05-10 22:22:40 -07:00
|
|
|
#endif
|
|
|
|
#ifndef POLLREMOVE
|
2018-02-01 15:13:18 -05:00
|
|
|
#define POLLREMOVE 0x1000
|
2007-05-10 22:22:40 -07:00
|
|
|
#endif
|
|
|
|
#ifndef POLLRDHUP
|
2018-02-01 15:13:18 -05:00
|
|
|
#define POLLRDHUP 0x2000
|
2007-05-10 22:22:40 -07:00
|
|
|
#endif
|
|
|
|
|
aio: fix use-after-free due to missing POLLFREE handling
signalfd_poll() and binder_poll() are special in that they use a
waitqueue whose lifetime is the current task, rather than the struct
file as is normally the case. This is okay for blocking polls, since a
blocking poll occurs within one task; however, non-blocking polls
require another solution. This solution is for the queue to be cleared
before it is freed, by sending a POLLFREE notification to all waiters.
Unfortunately, only eventpoll handles POLLFREE. A second type of
non-blocking poll, aio poll, was added in kernel v4.18, and it doesn't
handle POLLFREE. This allows a use-after-free to occur if a signalfd or
binder fd is polled with aio poll, and the waitqueue gets freed.
Fix this by making aio poll handle POLLFREE.
A patch by Ramji Jiyani <ramjiyani@google.com>
(https://lore.kernel.org/r/20211027011834.2497484-1-ramjiyani@google.com)
tried to do this by making aio_poll_wake() always complete the request
inline if POLLFREE is seen. However, that solution had two bugs.
First, it introduced a deadlock, as it unconditionally locked the aio
context while holding the waitqueue lock, which inverts the normal
locking order. Second, it didn't consider that POLLFREE notifications
are missed while the request has been temporarily de-queued.
The second problem was solved by my previous patch. This patch then
properly fixes the use-after-free by handling POLLFREE in a
deadlock-free way. It does this by taking advantage of the fact that
freeing of the waitqueue is RCU-delayed, similar to what eventpoll does.
Fixes: 2c14fa838cbe ("aio: implement IOCB_CMD_POLL")
Cc: <stable@vger.kernel.org> # v4.18+
Link: https://lore.kernel.org/r/20211209010455.42744-6-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
2021-12-08 17:04:55 -08:00
|
|
|
#define POLLFREE (__force __poll_t)0x4000
|
epoll: introduce POLLFREE to flush ->signalfd_wqh before kfree()
This patch is intentionally incomplete to simplify the review.
It ignores ep_unregister_pollwait() which plays with the same wqh.
See the next change.
epoll assumes that the EPOLL_CTL_ADD'ed file controls everything
f_op->poll() needs. In particular it assumes that the wait queue
can't go away until eventpoll_release(). This is not true in case
of signalfd, the task which does EPOLL_CTL_ADD uses its ->sighand
which is not connected to the file.
This patch adds the special event, POLLFREE, currently only for
epoll. It expects that init_poll_funcptr()'ed hook should do the
necessary cleanup. Perhaps it should be defined as EPOLLFREE in
eventpoll.
__cleanup_sighand() is changed to do wake_up_poll(POLLFREE) if
->signalfd_wqh is not empty, we add the new signalfd_cleanup()
helper.
ep_poll_callback(POLLFREE) simply does list_del_init(task_list).
This make this poll entry inconsistent, but we don't care. If you
share epoll fd which contains our sigfd with another process you
should blame yourself. signalfd is "really special". I simply do
not know how we can define the "right" semantics if it used with
epoll.
The main problem is, epoll calls signalfd_poll() once to establish
the connection with the wait queue, after that signalfd_poll(NULL)
returns the different/inconsistent results depending on who does
EPOLL_CTL_MOD/signalfd_read/etc. IOW: apart from sigmask, signalfd
has nothing to do with the file, it works with the current thread.
In short: this patch is the hack which tries to fix the symptoms.
It also assumes that nobody can take tasklist_lock under epoll
locks, this seems to be true.
Note:
- we do not have wake_up_all_poll() but wake_up_poll()
is fine, poll/epoll doesn't use WQ_FLAG_EXCLUSIVE.
- signalfd_cleanup() uses POLLHUP along with POLLFREE,
we need a couple of simple changes in eventpoll.c to
make sure it can't be "lost".
Reported-by: Maxime Bizon <mbizon@freebox.fr>
Cc: <stable@kernel.org>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-02-24 20:07:11 +01:00
|
|
|
|
2017-07-02 22:05:03 -04:00
|
|
|
#define POLL_BUSY_LOOP (__force __poll_t)0x8000
|
2013-06-24 10:28:03 +03:00
|
|
|
|
2007-05-10 22:22:40 -07:00
|
|
|
struct pollfd {
|
|
|
|
int fd;
|
|
|
|
short events;
|
|
|
|
short revents;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* __ASM_GENERIC_POLL_H */
|