--- Begin Message ---
this patch fixes the use-after-free of `pd`, and also fixes the leak
of `device`. let me know if you need this uploaded to github
instead...
diff --git a/tcpdump.c b/tcpdump.c
index 658d8b34..4fa390fd 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -2239,8 +2239,12 @@ main(int argc, char **argv)
error("%s", pcap_geterr(pd));
if (dflag) {
bpf_dump(&fcode, dflag);
- pcap_close(pd);
+ /* Clear pd so our signal handler won't use-after-free it. */
+ pcap_t *to_free = pd;
+ pd = NULL;
+ pcap_close(to_free);
free(cmdbuf);
+ free(device);
pcap_freecode(&fcode);
exit_tcpdump(S_SUCCESS);
}
@@ -2559,7 +2563,10 @@ DIAG_ON_CLANG(assign-enum)
*/
info(1);
}
- pcap_close(pd);
+ /* Clear pd so our signal handler won't use-after-free it. */
+ pcap_t *to_free = pd;
+ pd = NULL;
+ pcap_close(to_free);
if (VFileName != NULL) {
ret = get_next_file(VFile, VFileLine);
if (ret) {
@@ -2640,6 +2647,7 @@ DIAG_ON_CLANG(assign-enum)
PLURAL_SUFFIX(packets_captured));
free(cmdbuf);
+ free(device);
pcap_freecode(&fcode);
exit_tcpdump(status == -1 ? 1 : 0);
}
@@ -2692,7 +2700,8 @@ cleanup(int signo _U_)
* to do anything with standard I/O streams in a signal handler -
* the ANSI C standard doesn't say it is).
*/
- pcap_breakloop(pd);
+ if (pd != NULL)
+ pcap_breakloop(pd);
#else
/*
* We don't have "pcap_breakloop()"; this isn't safe, but
On Wed, Oct 14, 2020 at 2:28 PM enh <e...@google.com> wrote:
>
> i haven't reproduced it myself yet (though i'll try shortly) but we
> got an automated crash report from tcpdump on Android via
> [gwp-asan](https://developer.android.com/ndk/guides/gwp-asan).
>
> the bug is a use-after-free, specifically when pcap_breakloop() tries
> to write to the already-freed struct pcap_t. this happens if a signal
> is received during tcpdump shutdown (which is presumably why we
> haven't hit this more often on ASan/HWASan builds).
>
> i assume the fix is to disable the signal handlers before calling
> pcap_close() to free the struct pcap_t, but i thought i'd bring this
> up on the list before i (a) look at reproducing this locally and (b)
> send a patch...
diff --git a/tcpdump.c b/tcpdump.c
index 658d8b34..4fa390fd 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -2239,8 +2239,12 @@ main(int argc, char **argv)
error("%s", pcap_geterr(pd));
if (dflag) {
bpf_dump(&fcode, dflag);
- pcap_close(pd);
+ /* Clear pd so our signal handler won't use-after-free it. */
+ pcap_t *to_free = pd;
+ pd = NULL;
+ pcap_close(to_free);
free(cmdbuf);
+ free(device);
pcap_freecode(&fcode);
exit_tcpdump(S_SUCCESS);
}
@@ -2559,7 +2563,10 @@ DIAG_ON_CLANG(assign-enum)
*/
info(1);
}
- pcap_close(pd);
+ /* Clear pd so our signal handler won't use-after-free it. */
+ pcap_t *to_free = pd;
+ pd = NULL;
+ pcap_close(to_free);
if (VFileName != NULL) {
ret = get_next_file(VFile, VFileLine);
if (ret) {
@@ -2640,6 +2647,7 @@ DIAG_ON_CLANG(assign-enum)
PLURAL_SUFFIX(packets_captured));
free(cmdbuf);
+ free(device);
pcap_freecode(&fcode);
exit_tcpdump(status == -1 ? 1 : 0);
}
@@ -2692,7 +2700,8 @@ cleanup(int signo _U_)
* to do anything with standard I/O streams in a signal handler -
* the ANSI C standard doesn't say it is).
*/
- pcap_breakloop(pd);
+ if (pd != NULL)
+ pcap_breakloop(pd);
#else
/*
* We don't have "pcap_breakloop()"; this isn't safe, but
--- End Message ---
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers@lists.tcpdump.org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers