Skip to content

Commit f320ac6

Browse files
committed
Merge branch 'work.epoll' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull epoll fixes from Al Viro: "Fix reference counting and clean up exit paths" * 'work.epoll' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: do_epoll_ctl(): clean the failure exits up a bit epoll: Keep a reference on files added to the check list
2 parents c3d8f22 + 52c4796 commit f320ac6

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

fs/eventpoll.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,9 +1994,11 @@ static int ep_loop_check_proc(void *priv, void *cookie, int call_nests)
19941994
* not already there, and calling reverse_path_check()
19951995
* during ep_insert().
19961996
*/
1997-
if (list_empty(&epi->ffd.file->f_tfile_llink))
1997+
if (list_empty(&epi->ffd.file->f_tfile_llink)) {
1998+
get_file(epi->ffd.file);
19981999
list_add(&epi->ffd.file->f_tfile_llink,
19992000
&tfile_check_list);
2001+
}
20002002
}
20012003
}
20022004
mutex_unlock(&ep->mtx);
@@ -2040,6 +2042,7 @@ static void clear_tfile_check_list(void)
20402042
file = list_first_entry(&tfile_check_list, struct file,
20412043
f_tfile_llink);
20422044
list_del_init(&file->f_tfile_llink);
2045+
fput(file);
20432046
}
20442047
INIT_LIST_HEAD(&tfile_check_list);
20452048
}
@@ -2200,25 +2203,22 @@ int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *epds,
22002203
full_check = 1;
22012204
if (is_file_epoll(tf.file)) {
22022205
error = -ELOOP;
2203-
if (ep_loop_check(ep, tf.file) != 0) {
2204-
clear_tfile_check_list();
2206+
if (ep_loop_check(ep, tf.file) != 0)
22052207
goto error_tgt_fput;
2206-
}
2207-
} else
2208+
} else {
2209+
get_file(tf.file);
22082210
list_add(&tf.file->f_tfile_llink,
22092211
&tfile_check_list);
2212+
}
22102213
error = epoll_mutex_lock(&ep->mtx, 0, nonblock);
2211-
if (error) {
2212-
out_del:
2213-
list_del(&tf.file->f_tfile_llink);
2214+
if (error)
22142215
goto error_tgt_fput;
2215-
}
22162216
if (is_file_epoll(tf.file)) {
22172217
tep = tf.file->private_data;
22182218
error = epoll_mutex_lock(&tep->mtx, 1, nonblock);
22192219
if (error) {
22202220
mutex_unlock(&ep->mtx);
2221-
goto out_del;
2221+
goto error_tgt_fput;
22222222
}
22232223
}
22242224
}
@@ -2239,8 +2239,6 @@ int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *epds,
22392239
error = ep_insert(ep, epds, tf.file, fd, full_check);
22402240
} else
22412241
error = -EEXIST;
2242-
if (full_check)
2243-
clear_tfile_check_list();
22442242
break;
22452243
case EPOLL_CTL_DEL:
22462244
if (epi)
@@ -2263,8 +2261,10 @@ int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *epds,
22632261
mutex_unlock(&ep->mtx);
22642262

22652263
error_tgt_fput:
2266-
if (full_check)
2264+
if (full_check) {
2265+
clear_tfile_check_list();
22672266
mutex_unlock(&epmutex);
2267+
}
22682268

22692269
fdput(tf);
22702270
error_fput:

0 commit comments

Comments
 (0)