Skip to content

Commit 9ce209d

Browse files
davideltorvalds
authored andcommitted
epoll: avoid double-inserts in case of EFAULT
In commit f337b9c ("epoll: drop unnecessary test") Thomas found that there is an unnecessary (always true) test in ep_send_events(). The callback never inserts into ->rdllink while the send loop is performed, and also does the ~EP_PRIVATE_BITS test. Given we're holding the mutex during this time, the conditions tested inside the loop are always true. HOWEVER. The test "!ep_is_linked(&epi->rdllink)" wasn't there because we insert into ->rdllink, but because the send-events loop might terminate before the whole list is scanned (-EFAULT). In such cases, when the loop terminates early, and when a (leftover) file received an event while we're performing the lockless loop, we need such test to avoid to double insert the epoll items. The list_splice() done a few steps below, will correctly re-insert the ones that were left on "txlist". This should fix the kenrel.org bugzilla entry 11831. Signed-off-by: Davide Libenzi <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 4d36a9e commit 9ce209d

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

fs/eventpoll.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -930,8 +930,15 @@ static int ep_send_events(struct eventpoll *ep, struct epoll_event __user *event
930930
* inside the main ready-list here.
931931
*/
932932
for (nepi = ep->ovflist; (epi = nepi) != NULL;
933-
nepi = epi->next, epi->next = EP_UNACTIVE_PTR)
934-
list_add_tail(&epi->rdllink, &ep->rdllist);
933+
nepi = epi->next, epi->next = EP_UNACTIVE_PTR) {
934+
/*
935+
* If the above loop quit with errors, the epoll item might still
936+
* be linked to "txlist", and the list_splice() done below will
937+
* take care of those cases.
938+
*/
939+
if (!ep_is_linked(&epi->rdllink))
940+
list_add_tail(&epi->rdllink, &ep->rdllist);
941+
}
935942
/*
936943
* We need to set back ep->ovflist to EP_UNACTIVE_PTR, so that after
937944
* releasing the lock, events will be queued in the normal way inside

0 commit comments

Comments
 (0)