From: Felix Fietkau Date: Sun, 24 Jun 2012 19:06:16 +0000 (+0200) Subject: uloop: prevent fd callbacks for unregistered fds by ensuring that pointers in the... X-Git-Url: http://git.archive.openwrt.org/?p=project%2Flibubox.git;a=commitdiff_plain;h=63bc6593c37b4757199fb65ec1fb607c5e5190e3 uloop: prevent fd callbacks for unregistered fds by ensuring that pointers in the epoll array are cleared --- diff --git a/uloop.c b/uloop.c index f226f50..bdda0cf 100644 --- a/uloop.c +++ b/uloop.c @@ -201,16 +201,26 @@ static int register_poll(struct uloop_fd *fd, unsigned int flags) return epoll_ctl(poll_fd, op, fd->fd, &ev); } +static int cur_fd, cur_nfds; +static struct epoll_event events[ULOOP_MAX_EVENTS]; + int uloop_fd_delete(struct uloop_fd *sock) { + int i; + + for (i = cur_fd + 1; i < cur_nfds; i++) { + if (events[i].data.ptr != sock) + continue; + + events[i].data.ptr = NULL; + } sock->registered = false; return epoll_ctl(poll_fd, EPOLL_CTL_DEL, sock->fd, 0); } static void uloop_run_events(int timeout) { - struct epoll_event events[ULOOP_MAX_EVENTS]; - int nfds, n; + int n, nfds; nfds = epoll_wait(poll_fd, events, ARRAY_SIZE(events), timeout); for(n = 0; n < nfds; ++n) @@ -218,6 +228,9 @@ static void uloop_run_events(int timeout) struct uloop_fd *u = events[n].data.ptr; unsigned int ev = 0; + if (!u) + continue; + if(events[n].events & EPOLLERR) { u->error = true; uloop_fd_delete(u); @@ -235,9 +248,13 @@ static void uloop_run_events(int timeout) if(events[n].events & EPOLLOUT) ev |= ULOOP_WRITE; - if(u->cb) + if(u->cb) { + cur_fd = n; + cur_nfds = nfds; u->cb(u, ev); + } } + cur_nfds = 0; } #endif