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>
This commit is contained in:

committed by
Stefano Brivio

parent
3401644453
commit
6a6735ece4
8
pasta.c
8
pasta.c
@@ -365,7 +365,10 @@ void pasta_ns_conf(struct ctx *c)
|
||||
int pasta_netns_quit_init(struct ctx *c)
|
||||
{
|
||||
int flags = O_NONBLOCK | O_CLOEXEC;
|
||||
struct epoll_event ev = { .events = EPOLLIN };
|
||||
union epoll_ref ref = { .type = EPOLL_TYPE_NSQUIT };
|
||||
struct epoll_event ev = {
|
||||
.events = EPOLLIN
|
||||
};
|
||||
int inotify_fd;
|
||||
|
||||
if (c->mode != MODE_PASTA || c->no_netns_quit || !*c->netns_base)
|
||||
@@ -381,7 +384,8 @@ int pasta_netns_quit_init(struct ctx *c)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ev.data.fd = inotify_fd;
|
||||
ref.fd = inotify_fd;
|
||||
ev.data.u64 = ref.u64;
|
||||
epoll_ctl(c->epollfd, EPOLL_CTL_ADD, inotify_fd, &ev);
|
||||
|
||||
return inotify_fd;
|
||||
|
Reference in New Issue
Block a user