Messages in this thread Patch in this message | | | From | "Jay Vosburgh" <> | Date | Wed, 6 Nov 2002 15:06:45 -0700 | Subject | [PATCH] 2.5.46: epoll_wait can return too many events |
| |
The logic in fs/eventpoll.c:ep_events_transfer() to bundle events can return more than the requested number of events (because the event count is only incremented for each bundle); this will scribble on memory beyond the end of the user's buffer. The fix is to test against the bundle size (ebufcnt) plus the event count (eventcnt).
Also, passing maxevents <= 0 to epoll_wait() causes the system to lock up; the fix is to return EINVAL if maxevents is <= 0.
-J
--- linux-2.5.46.orig/fs/eventpoll.c Wed Nov 6 12:20:46 2002 +++ linux-2.5.46/fs/eventpoll.c Wed Nov 6 12:48:08 2002 @@ -457,6 +457,9 @@ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d)\n", current, epfd, events, maxevents, timeout));
+ if (maxevents <= 0) + return -EINVAL; + /* Verify that the area passed by the user is writeable */ if ((error = verify_area(VERIFY_WRITE, events, maxevents * sizeof(struct pollfd)))) goto eexit_1; @@ -1068,7 +1071,7 @@
write_lock_irqsave(&ep->lock, flags);
- for (eventcnt = 0, ebufcnt = 0; eventcnt < maxevents && !list_empty(lsthead);) { + for (eventcnt = 0, ebufcnt = 0; (ebufcnt + eventcnt) < maxevents && !list_empty(lsthead);) { struct epitem *dpi = list_entry(lsthead->next, struct epitem, rdllink);
/* Remove the item from the ready list */ (See attached file: epoll-2.5.46-maxevent.patch)
[unhandled content-type:application/octet-stream]
| |