Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'work.epoll' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull epoll fixes from Al Viro:
"Several race fixes in epoll"

* 'work.epoll' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
ep_create_wakeup_source(): dentry name can change under you...
epoll: EPOLL_CTL_ADD: close the race in decision to take fast path
epoll: replace ->visited/visited_list with generation count
epoll: do not insert into poll queues until all sanity checks are done

+31 -41
+31 -41
fs/eventpoll.c
··· 218 218 struct file *file; 219 219 220 220 /* used to optimize loop detection check */ 221 - struct list_head visited_list_link; 222 - int visited; 221 + u64 gen; 223 222 224 223 #ifdef CONFIG_NET_RX_BUSY_POLL 225 224 /* used to track busy poll napi_id */ ··· 273 274 */ 274 275 static DEFINE_MUTEX(epmutex); 275 276 277 + static u64 loop_check_gen = 0; 278 + 276 279 /* Used to check for epoll file descriptor inclusion loops */ 277 280 static struct nested_calls poll_loop_ncalls; 278 281 ··· 283 282 284 283 /* Slab cache used to allocate "struct eppoll_entry" */ 285 284 static struct kmem_cache *pwq_cache __read_mostly; 286 - 287 - /* Visited nodes during ep_loop_check(), so we can unset them when we finish */ 288 - static LIST_HEAD(visited_list); 289 285 290 286 /* 291 287 * List of files with newly added links, where we may need to limit the number ··· 1448 1450 1449 1451 static int ep_create_wakeup_source(struct epitem *epi) 1450 1452 { 1451 - const char *name; 1453 + struct name_snapshot n; 1452 1454 struct wakeup_source *ws; 1453 1455 1454 1456 if (!epi->ep->ws) { ··· 1457 1459 return -ENOMEM; 1458 1460 } 1459 1461 1460 - name = epi->ffd.file->f_path.dentry->d_name.name; 1461 - ws = wakeup_source_register(NULL, name); 1462 + take_dentry_name_snapshot(&n, epi->ffd.file->f_path.dentry); 1463 + ws = wakeup_source_register(NULL, n.name.name); 1464 + release_dentry_name_snapshot(&n); 1462 1465 1463 1466 if (!ws) 1464 1467 return -ENOMEM; ··· 1521 1522 RCU_INIT_POINTER(epi->ws, NULL); 1522 1523 } 1523 1524 1525 + /* Add the current item to the list of active epoll hook for this file */ 1526 + spin_lock(&tfile->f_lock); 1527 + list_add_tail_rcu(&epi->fllink, &tfile->f_ep_links); 1528 + spin_unlock(&tfile->f_lock); 1529 + 1530 + /* 1531 + * Add the current item to the RB tree. All RB tree operations are 1532 + * protected by "mtx", and ep_insert() is called with "mtx" held. 1533 + */ 1534 + ep_rbtree_insert(ep, epi); 1535 + 1536 + /* now check if we've created too many backpaths */ 1537 + error = -EINVAL; 1538 + if (full_check && reverse_path_check()) 1539 + goto error_remove_epi; 1540 + 1524 1541 /* Initialize the poll table using the queue callback */ 1525 1542 epq.epi = epi; 1526 1543 init_poll_funcptr(&epq.pt, ep_ptable_queue_proc); ··· 1558 1543 error = -ENOMEM; 1559 1544 if (epi->nwait < 0) 1560 1545 goto error_unregister; 1561 - 1562 - /* Add the current item to the list of active epoll hook for this file */ 1563 - spin_lock(&tfile->f_lock); 1564 - list_add_tail_rcu(&epi->fllink, &tfile->f_ep_links); 1565 - spin_unlock(&tfile->f_lock); 1566 - 1567 - /* 1568 - * Add the current item to the RB tree. All RB tree operations are 1569 - * protected by "mtx", and ep_insert() is called with "mtx" held. 1570 - */ 1571 - ep_rbtree_insert(ep, epi); 1572 - 1573 - /* now check if we've created too many backpaths */ 1574 - error = -EINVAL; 1575 - if (full_check && reverse_path_check()) 1576 - goto error_remove_epi; 1577 1546 1578 1547 /* We have to drop the new item inside our item list to keep track of it */ 1579 1548 write_lock_irq(&ep->lock); ··· 1587 1588 1588 1589 return 0; 1589 1590 1591 + error_unregister: 1592 + ep_unregister_pollwait(ep, epi); 1590 1593 error_remove_epi: 1591 1594 spin_lock(&tfile->f_lock); 1592 1595 list_del_rcu(&epi->fllink); 1593 1596 spin_unlock(&tfile->f_lock); 1594 1597 1595 1598 rb_erase_cached(&epi->rbn, &ep->rbr); 1596 - 1597 - error_unregister: 1598 - ep_unregister_pollwait(ep, epi); 1599 1599 1600 1600 /* 1601 1601 * We need to do this because an event could have been arrived on some ··· 1970 1972 struct epitem *epi; 1971 1973 1972 1974 mutex_lock_nested(&ep->mtx, call_nests + 1); 1973 - ep->visited = 1; 1974 - list_add(&ep->visited_list_link, &visited_list); 1975 + ep->gen = loop_check_gen; 1975 1976 for (rbp = rb_first_cached(&ep->rbr); rbp; rbp = rb_next(rbp)) { 1976 1977 epi = rb_entry(rbp, struct epitem, rbn); 1977 1978 if (unlikely(is_file_epoll(epi->ffd.file))) { 1978 1979 ep_tovisit = epi->ffd.file->private_data; 1979 - if (ep_tovisit->visited) 1980 + if (ep_tovisit->gen == loop_check_gen) 1980 1981 continue; 1981 1982 error = ep_call_nested(&poll_loop_ncalls, 1982 1983 ep_loop_check_proc, epi->ffd.file, ··· 2016 2019 */ 2017 2020 static int ep_loop_check(struct eventpoll *ep, struct file *file) 2018 2021 { 2019 - int ret; 2020 - struct eventpoll *ep_cur, *ep_next; 2021 - 2022 - ret = ep_call_nested(&poll_loop_ncalls, 2022 + return ep_call_nested(&poll_loop_ncalls, 2023 2023 ep_loop_check_proc, file, ep, current); 2024 - /* clear visited list */ 2025 - list_for_each_entry_safe(ep_cur, ep_next, &visited_list, 2026 - visited_list_link) { 2027 - ep_cur->visited = 0; 2028 - list_del(&ep_cur->visited_list_link); 2029 - } 2030 - return ret; 2031 2024 } 2032 2025 2033 2026 static void clear_tfile_check_list(void) ··· 2182 2195 goto error_tgt_fput; 2183 2196 if (op == EPOLL_CTL_ADD) { 2184 2197 if (!list_empty(&f.file->f_ep_links) || 2198 + ep->gen == loop_check_gen || 2185 2199 is_file_epoll(tf.file)) { 2186 2200 mutex_unlock(&ep->mtx); 2187 2201 error = epoll_mutex_lock(&epmutex, 0, nonblock); 2188 2202 if (error) 2189 2203 goto error_tgt_fput; 2204 + loop_check_gen++; 2190 2205 full_check = 1; 2191 2206 if (is_file_epoll(tf.file)) { 2192 2207 error = -ELOOP; ··· 2252 2263 error_tgt_fput: 2253 2264 if (full_check) { 2254 2265 clear_tfile_check_list(); 2266 + loop_check_gen++; 2255 2267 mutex_unlock(&epmutex); 2256 2268 } 2257 2269