Skip to content

Commit 5b963e9

Browse files
committed
rpcap: verify control socket status during reception
Signed-off-by: Kevin Boulain <[email protected]> Signed-off-by: Gabriel Ganne <[email protected]>
1 parent 7f14bee commit 5b963e9

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

pcap-rpcap.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,12 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
416416
/*
417417
* 'fp->rmt_sockdata' has always to be set before calling the select(),
418418
* since it is cleared by the select()
419+
*
420+
* While not strictly necessary, it's best to include the control socket.
421+
* It allows us to check for a connection drop as the data socket may use UDP
422+
* and as such, is without any mean to report back any error to the client.
419423
*/
424+
FD_SET(pr->rmt_sockctrl, &rfds);
420425
FD_SET(pr->rmt_sockdata, &rfds);
421426

422427
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
@@ -439,8 +444,22 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
439444
}
440445
}
441446

447+
/*
448+
* In the rpcap protocol, once the capture starts, the control socket isn't
449+
* used anymore until the capture ends.
450+
* However, it's the only way to check for connection errors
451+
* as the data socket may uses UDP.
452+
*/
453+
if (FD_ISSET(pr->rmt_sockctrl, &rfds)) {
454+
uint8 byte;
455+
const int nread = sock_recv(pr->rmt_sockctrl, pr->ctrl_ssl, &byte, sizeof(byte),
456+
SOCK_MSG_PEEK | SOCK_EOF_IS_ERROR, p->errbuf, PCAP_ERRBUF_SIZE);
457+
if (nread == -1)
458+
return -1;
459+
}
460+
442461
/* There is no data waiting, so return '0' */
443-
if (retval == 0)
462+
if (!FD_ISSET(pr->rmt_sockdata, &rfds))
444463
return 0;
445464

446465
/*

0 commit comments

Comments
 (0)