Skip to content

Commit

Permalink
fprintf(3) should not be used by signal handlers
Browse files Browse the repository at this point in the history
On most OS platforms fprintf() et.al. are considered to be signal unsafe. I've
noticed the signal handlers in tcpdump call fprintf(). The patch below defers
call to fprintf() triggered by signal to pcap_loop callback.

Submitted to upstream:
the-tcpdump-group#638
  • Loading branch information
alexandr nedvedicky - Sun Microsystems - Prague Czech Republic committed Apr 17, 2019
1 parent 9779061 commit 906dbf6
Showing 1 changed file with 27 additions and 22 deletions.
49 changes: 27 additions & 22 deletions tcpdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ static int WflagChars;
static char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */
static int immediate_mode;

static int infodelay;
static int infoprint;
static int gotalarm;

char *program_name;

Expand Down Expand Up @@ -1962,6 +1962,8 @@ main(int argc, char **argv)
#elif defined(HAVE_ALARM)
(void)setsignal(SIGALRM, verbose_stats_dump);
alarm(1);
/* signal alarm to get the first iteration ASAP */
gotalarm = 1;
#endif
}

Expand Down Expand Up @@ -2274,8 +2276,6 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s

++packets_captured;

++infodelay;

dump_info = (struct dump_info *)user;

/*
Expand Down Expand Up @@ -2464,41 +2464,52 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
pcap_dump_flush(dump_info->p);
#endif

--infodelay;
if (infoprint)
if (infoprint) {
info(0);
infoprint = 0;
}

if (gotalarm) {
fprintf(stderr, "Got %u\r", packets_captured);
gotalarm = 0;
alarm(1);
}
}

static void
dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
{
++packets_captured;

++infodelay;

pcap_dump(user, h, sp);
#ifdef HAVE_PCAP_DUMP_FLUSH
if (Uflag)
pcap_dump_flush((pcap_dumper_t *)user);
#endif

--infodelay;
if (infoprint)
if (infoprint) {
info(0);
infoprint = 0;
}

if (gotalarm) {
fprintf(stderr, "Got %u\r", packets_captured);
gotalarm = 0;
alarm(1);
}
}

static void
print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
{
++packets_captured;

++infodelay;

pretty_print_packet((netdissect_options *)user, h, sp, packets_captured);

--infodelay;
if (infoprint)
if (infoprint) {
info(0);
infoprint = 0;
}
}

#ifdef _WIN32
Expand Down Expand Up @@ -2531,10 +2542,7 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
#ifdef SIGNAL_REQ_INFO
RETSIGTYPE requestinfo(int signo _U_)
{
if (infodelay)
++infoprint;
else
info(0);
infoprint = 1;
}
#endif

Expand All @@ -2545,15 +2553,12 @@ RETSIGTYPE requestinfo(int signo _U_)
void CALLBACK verbose_stats_dump (UINT timer_id _U_, UINT msg _U_, DWORD_PTR arg _U_,
DWORD_PTR dw1 _U_, DWORD_PTR dw2 _U_)
{
if (infodelay == 0)
fprintf(stderr, "Got %u\r", packets_captured);
gotalarm = 1;
}
#elif defined(HAVE_ALARM)
static void verbose_stats_dump(int sig _U_)
{
if (infodelay == 0)
fprintf(stderr, "Got %u\r", packets_captured);
alarm(1);
gotalarm = 1;
}
#endif

Expand Down

0 comments on commit 906dbf6

Please sign in to comment.