On Thu, 17 Nov 2022 15:33:06 +0000 "Richard W.M. Jones" <rjones(a)redhat.com> wrote:On Thu, Nov 17, 2022 at 04:26:40PM +0100, Stefano Brivio wrote:Out-of-band, so to speak: we won't even recv() if we get EPOLLRDHUP (that's handled in tap_handler()). If I do this on top of this patch: --- a/tap.c +++ b/tap.c @@ -1073,7 +1073,7 @@ void tap_sock_init(struct ctx *c) struct epoll_event ev = { 0 }; ev.data.fd = c->fd_tap; - ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP; + ev.events = EPOLLIN | EPOLLET; Then it gets those four bytes: [pid 2538704] epoll_wait(5, 0x7ffedc4a6320, 8, 1000) = 1 [pid 2538704] recvfrom(4, 0x560797677000, 8323069, MSG_DONTWAIT, NULL, NULL) = 4 [pid 2538704] epoll_wait(5, [], 8, 1000) = 0 [pid 2538704] epoll_wait(5, 0x7ffedc4a6320, 8, 1000) = -1 EINTR (Interrupted system call) and does nothing with them, as expected. Two epoll_wait() calls later, the syscall is interrupted, I'm not sure why and how we should react (in main(), passt.c) in that case.From: "Richard W.M. Jones" <rjones(a)redhat.com> This passes a fully connected stream socket to passt. Signed-off-by: Richard W.M. Jones <rjones(a)redhat.com> [sbrivio: reuse fd_tap instead of adding a new descriptor, imply --one-off on --fd, add to optstring and usage()] Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- v2: - reuse fd_tap, we don't need a separate file descriptor - add F to optstring and usage(), for both passt and pasta - imply --one-off, we can't do much once the socket is closed With this, the trick from 5/5 goes a bit further: passt reads from the file descriptor passed by the wrapper.Thanks for the v2 .. I'll add it to my series and play with it.However, we get EPOLLRDHUP right away, from the close() on one end of the socket pair I guess. Should we just ignore all EPOLLRDHUP events, just the first one...?Does it see the event out-of-band or does it get an in-band read(2) == 0 after finishing reading the data?Ideally what should happen is that passt reads and parses all or as much of the data as it can, and then it responds to the closed socket by exiting. The reason for this is so that we have as much opportunity as possible to break the parser and crash passt.So probably ignoring EPOLLRDHUP is safe. If the socket is closed we should get EPOLLHUP.If passt was exiting before fully reading/parsing everything that it could, then we wouldn't be fuzzing the parser as deeply as we can.We would process a EPOLLRDHUP or EPOLLHUP before doing anything, yes (also in tap_handler()). But if we get a EPOLLIN event first, then it's fine, we'll read everything.Note that the fuzzer will (quite routinely and normally) create test cases which are total nonsense, eg. packets with incorrect length field, truncated final packet, etc.Yes yes, I can imagine. :) -- Stefano