diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2023-08-11 15:12:22 +1000 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2023-08-13 17:29:53 +0200 |
commit | 6a6735ece442298e000de43f5325842a442c263d (patch) | |
tree | a810b909c527ddea425d6887fc598c5740efd27c /passt.c | |
parent | 34016444534120f2fa5a049675815843d041bc16 (diff) | |
download | passt-6a6735ece442298e000de43f5325842a442c263d.tar passt-6a6735ece442298e000de43f5325842a442c263d.tar.gz passt-6a6735ece442298e000de43f5325842a442c263d.tar.bz2 passt-6a6735ece442298e000de43f5325842a442c263d.tar.lz passt-6a6735ece442298e000de43f5325842a442c263d.tar.xz passt-6a6735ece442298e000de43f5325842a442c263d.tar.zst passt-6a6735ece442298e000de43f5325842a442c263d.zip |
epoll: Always use epoll_ref for the epoll data variable
epoll_ref contains a variety of information useful when handling epoll
events on our sockets, and we place it in the epoll_event data field
returned by epoll. However, for a few other things we use the 'fd' field
in the standard union of types for that data field.
This actually introduces a bug which is vanishingly unlikely to hit in
practice, but very nasty if it ever did: theoretically if we had a very
large file descriptor number for fd_tap or fd_tap_listen it could overflow
into bits that overlap with the 'proto' field in epoll_ref. With some
very bad luck this could mean that we mistakenly think an event on a
regular socket is an event on fd_tap or fd_tap_listen.
More practically, using different (but overlapping) fields of the
epoll_data means we can't unify dispatch for the various different objects
in the epoll. Therefore use the same epoll_ref as the data for the tap
fds and the netns quit fd, adding new fd type values to describe them.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'passt.c')
-rw-r--r-- | passt.c | 11 |
1 files changed, 6 insertions, 5 deletions
@@ -60,6 +60,8 @@ char *epoll_type_str[EPOLL_TYPE_MAX + 1] = { [EPOLL_TYPE_UDP] = "UDP socket", [EPOLL_TYPE_ICMP] = "ICMP socket", [EPOLL_TYPE_ICMPV6] = "ICMPv6 socket", + [EPOLL_TYPE_NSQUIT] = "namespace inotify", + [EPOLL_TYPE_TAP] = "tap device", }; /** @@ -328,12 +330,11 @@ loop: for (i = 0; i < nfds; i++) { union epoll_ref ref = *((union epoll_ref *)&events[i].data.u64); - int fd = events[i].data.fd; - if (fd == c.fd_tap || fd == c.fd_tap_listen) - tap_handler(&c, fd, events[i].events, &now); - else if (fd == quit_fd) - pasta_netns_quit_handler(&c, fd); + if (ref.type == EPOLL_TYPE_TAP) + tap_handler(&c, ref.fd, events[i].events, &now); + else if (ref.type == EPOLL_TYPE_NSQUIT) + pasta_netns_quit_handler(&c, quit_fd); else sock_handler(&c, ref, events[i].events, &now); } |