On 23/02/2023 18:53, Tudor Cretu wrote:
Move the logic that copies an epoll_event from user to its own function and expose it in the eventpoll.h header. This allows other subsystems such as io_uring to handle epoll_events.
Signed-off-by: Tudor Cretu tudor.cretu@arm.com
fs/eventpoll.c | 39 ++++++++++++++++++++++++++------------- include/linux/eventpoll.h | 4 ++++ 2 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 7e33a2781dec8..faa493a279bd0 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -2197,6 +2197,28 @@ int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *epds, return error; } +static int get_compat_epoll_event(struct epoll_event *epds,
const void __user *user_epds)
+{
- struct compat_epoll_event compat_epds;
- if (unlikely(copy_from_user(&compat_epds, user_epds, sizeof(compat_epds))))
return -EFAULT;
- epds->events = compat_epds.events;
- epds->data = (__kernel_uintptr_t)as_user_ptr(compat_epds.data);
- return 0;
+}
+int copy_epoll_event_from_user(struct epoll_event *epds,
const void __user *user_epds,
bool compat)
+{
- if (compat)
return get_compat_epoll_event(epds, user_epds);
- return copy_from_user_with_ptr(epds, user_epds, sizeof(*epds));
+}
Nit: just one empty line is enough.
Kevin
/*
- The following function implements the controller interface for
- the eventpoll file that enables the insertion/removal/change of
@@ -2211,20 +2233,11 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event epds; if (ep_op_has_event(op)) {
if (in_compat_syscall()) {
struct compat_epoll_event compat_epds;
if (copy_from_user(&compat_epds, event,
sizeof(struct compat_epoll_event)))
return -EFAULT;
int ret;
epds.events = compat_epds.events;
epds.data = (__kernel_uintptr_t)as_user_ptr(compat_epds.data);
} else {
if (copy_from_user_with_ptr(&epds, event,
sizeof(struct epoll_event)))
return -EFAULT;
}
ret = copy_epoll_event_from_user(&epds, event, in_compat_syscall());
if (ret)
}return -EFAULT;
return do_epoll_ctl(epfd, op, fd, &epds, false); diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h index 457811d82ff20..62b0829354a0e 100644 --- a/include/linux/eventpoll.h +++ b/include/linux/eventpoll.h @@ -103,4 +103,8 @@ epoll_put_uevent(__poll_t revents, __kernel_uintptr_t data, } #endif +int copy_epoll_event_from_user(struct epoll_event *epds,
const void __user *user_epds,
bool compat);
#endif /* #ifndef _LINUX_EVENTPOLL_H */