From faf16fb8103d8dcc335dcaee7273b6ee821e432d Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sun, 6 Nov 2022 05:31:51 +0800 Subject: [PATCH] vfs/epoll: Protect epoll_ctl by mutex Signed-off-by: Xiang Xiao --- fs/vfs/fs_epoll.c | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/fs/vfs/fs_epoll.c b/fs/vfs/fs_epoll.c index 81687af8720..7d923c128ba 100644 --- a/fs/vfs/fs_epoll.c +++ b/fs/vfs/fs_epoll.c @@ -181,7 +181,7 @@ static int epoll_do_create(int size, int flags) if (eph == NULL) { set_errno(ENOMEM); - return -1; + return ERROR; } nxmutex_init(&eph->lock); @@ -206,7 +206,7 @@ static int epoll_do_create(int size, int flags) nxmutex_destroy(&eph->lock); kmm_free(eph); set_errno(-fd); - return -1; + return ERROR; } return fd; @@ -275,15 +275,22 @@ void epoll_close(int epfd) * ****************************************************************************/ -int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev) +int epoll_ctl(int epfd, int op, int fd, FAR struct epoll_event *ev) { FAR struct epoll_head *eph; + int ret; int i; eph = epoll_head_from_fd(epfd); if (eph == NULL) { - return -1; + return ERROR; + } + + ret = nxmutex_lock(&eph->lock); + if (ret < 0) + { + goto err_without_lock; } switch (op) @@ -293,16 +300,16 @@ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev) epfd, eph->occupied, fd, ev->events); if (eph->occupied >= eph->size) { - set_errno(ENOMEM); - return -1; + ret = -ENOMEM; + goto err; } for (i = 1; i <= eph->occupied; i++) { if (eph->poll[i].fd == fd) { - set_errno(EEXIST); - return -1; + ret = -EEXIST; + goto err; } } @@ -331,8 +338,8 @@ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev) if (i > eph->occupied) { - set_errno(ENOENT); - return -1; + ret = -ENOENT; + goto err; } eph->occupied--; @@ -353,19 +360,26 @@ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev) if (i > eph->occupied) { - set_errno(ENOENT); - return -1; + ret = -ENOENT; + goto err; } break; default: - set_errno(EINVAL); - return -1; + ret = -EINVAL; + goto err; } + nxmutex_unlock(&eph->lock); poll_notify(&eph->poll, 1, POLLIN); - return 0; + return OK; + +err: + nxmutex_unlock(&eph->lock); +err_without_lock: + set_errno(-ret); + return ERROR; } /**************************************************************************** @@ -386,7 +400,7 @@ int epoll_pwait(int epfd, FAR struct epoll_event *evs, eph = epoll_head_from_fd(epfd); if (eph == NULL) { - return -1; + return ERROR; } if (timeout >= 0)