Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug #484 CVE-2018-17582 Check for corrupt PCAP files #491

Merged
merged 1 commit into from
Oct 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ dnl $Id$
AC_PREREQ([2.69])

dnl Set version info here!
AC_INIT([tcpreplay],[4.3.0-beta1],
AC_INIT([tcpreplay],[4.3.0-beta2],
[https://github.com/appneta/tcpreplay/issues],
[tcpreplay],
[http://tcpreplay.sourceforge.net/])
Expand Down
3 changes: 3 additions & 0 deletions docs/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
10/18/2018 Version 4.3.0 beta2
- CVE-2018-17582 heap-buffer-overflow in get_next_packet (#484)

01/18/2018 Version 4.3.0 beta1
- Travis CI build fails due to new build images (#432)
- Unable to build with libpcap 1.8.1 (#430)
Expand Down
55 changes: 54 additions & 1 deletion src/common/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ _our_safe_malloc(size_t len, const char *funcname, const int line, const char *f
u_char *ptr;

if ((ptr = malloc(len)) == NULL) {
fprintf(stderr, "ERROR in %s:%s() line %d: Unable to malloc() %zu bytes", file, funcname, line, len);
fprintf(stderr, "ERROR in %s:%s() line %d: Unable to malloc() %zu bytes/n",
file, funcname, line, len);
exit(-1);
}

Expand Down Expand Up @@ -119,6 +120,58 @@ _our_safe_free(void *ptr, const char *funcname, const int line, const char *file
ptr = NULL;
}

/**
* get next packet in pcap file
*/
#define MAX_PCAP_PACKET_LEN (262144) /* this matches Wireshark maximum size */
u_char *_our_safe_pcap_next(pcap_t *pcap, struct pcap_pkthdr *pkthdr,
const char *funcname, const int line, const char *file)
{
u_char *pktdata = (u_char *)pcap_next(pcap, pkthdr);

if (pktdata) {
if (pkthdr->len > MAX_PCAP_PACKET_LEN) {
fprintf(stderr, "safe_pcap_next ERROR: Invalid packet length in %s:%s() line %d: %u is greater than maximum %u\n",
file, funcname, line, pkthdr->len, MAX_PCAP_PACKET_LEN);
exit(-1);
}

if (pkthdr->len < pkthdr->caplen) {
fprintf(stderr, "safe_pcap_next ERROR: Invalid packet length in %s:%s() line %d: packet length %u is less than capture length %u\n",
file, funcname, line, pkthdr->len, pkthdr->caplen);
exit(-1);
}
}

return pktdata;
}

/**
* get next packet in pcap file (extended)
*/
int _our_safe_pcap_next_ex(pcap_t *pcap, struct pcap_pkthdr **pkthdr,
const u_char **pktdata, const char *funcname,
const int line, const char *file)
{
int res = pcap_next_ex(pcap, pkthdr, pktdata);

if (*pktdata && *pkthdr) {
if ((*pkthdr)->len > MAX_PCAP_PACKET_LEN) {
fprintf(stderr, "safe_pcap_next_ex ERROR: Invalid packet length in %s:%s() line %d: %u is greater than maximum %u\n",
file, funcname, line, (*pkthdr)->len, MAX_PCAP_PACKET_LEN);
exit(-1);
}

if ((*pkthdr)->len < (*pkthdr)->caplen) {
fprintf(stderr, "safe_pcap_next_ex ERROR: Invalid packet length in %s:%s() line %d: packet length %u is less than capture length %u\n",
file, funcname, line, (*pkthdr)->len, (*pkthdr)->caplen);
exit(-1);
}
}

return res;
}

/**
* Print various packet statistics
*/
Expand Down
9 changes: 9 additions & 0 deletions src/common/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ char *_our_safe_strdup(const char *str, const char *, const int, const char *);
#define safe_free(x) _our_safe_free(x, __FUNCTION__, __LINE__, __FILE__)
void _our_safe_free(void *ptr, const char *, const int, const char *);

#define safe_pcap_next(x, y) _our_safe_pcap_next(x, y, __FUNCTION__, __LINE__, __FILE__)
u_char *_our_safe_pcap_next(pcap_t *pcap, struct pcap_pkthdr *pkthdr,
const char *funcname, const int line, const char *file);

#define safe_pcap_next_ex(x, y, z) _our_safe_pcap_next_ex(x, y, z, __FUNCTION__, __LINE__, __FILE__)
int _our_safe_pcap_next_ex(pcap_t *pcap, struct pcap_pkthdr **pkthdr,
const u_char **pktdata, const char *funcname,
const int line, const char *file);

#define MAX_ARGS 128

#ifndef HAVE_INET_ATON
Expand Down
3 changes: 1 addition & 2 deletions src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,7 @@
slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK

/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR

/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
Expand Down
4 changes: 2 additions & 2 deletions src/send_packets.c
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ get_next_packet(tcpreplay_t *ctx, pcap_t *pcap, struct pcap_pkthdr *pkthdr, int
/*
* We should read the pcap file, and cache the results
*/
pktdata = (u_char *)pcap_next(pcap, pkthdr);
pktdata = safe_pcap_next(pcap, pkthdr);
if (pktdata != NULL) {
if (*prev_packet == NULL) {
/*
Expand Down Expand Up @@ -1051,7 +1051,7 @@ get_next_packet(tcpreplay_t *ctx, pcap_t *pcap, struct pcap_pkthdr *pkthdr, int
/*
* Read pcap file as normal
*/
pktdata = (u_char *)pcap_next(pcap, pkthdr);
pktdata = safe_pcap_next(pcap, pkthdr);
}

/* this get's casted to a const on the way out */
Expand Down
4 changes: 2 additions & 2 deletions src/tcpliveplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ setup_sched(struct tcp_sched* sched){
}

/*Before sending any packet, setup the schedule with the proper parameters*/
while((packet = pcap_next(local_handle,&header))) {
while((packet = safe_pcap_next(local_handle,&header))) {
pkt_counter++; /*increment number of packets seen*/

memcpy(&sched[i].pkthdr, &header, sizeof(struct pcap_pkthdr));
Expand Down Expand Up @@ -985,7 +985,7 @@ rewrite(input_addr* new_remoteip, struct mac_addr* new_remotemac, input_addr* my
}

/*Modify each packet's IP & MAC based on the passed args then do a checksum of each packet*/
for (pkt_counter = 0; pcap_next_ex(pcap, &header, &packet) > 0; pkt_counter++){
for (pkt_counter = 0; safe_pcap_next_ex(pcap, &header, &packet) > 0; pkt_counter++){

if (!warned && header->len > header->caplen) {
fprintf(stderr, "warning: packet capture truncated to %d byte packets\n",
Expand Down
2 changes: 1 addition & 1 deletion src/tcpprep.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ process_raw_packets(pcap_t * pcap)

assert(pcap);

while ((pktdata = pcap_next(pcap, &pkthdr)) != NULL) {
while ((pktdata = safe_pcap_next(pcap, &pkthdr)) != NULL) {
packetnum++;

dbgx(1, "Packet " COUNTER_SPEC, packetnum);
Expand Down
2 changes: 1 addition & 1 deletion src/tcprewrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ rewrite_packets(tcpedit_t *tcpedit, pcap_t *pin, pcap_dumper_t *pout)
* Keep sending while we have packets or until
* we've sent enough packets
*/
while ((pktconst = pcap_next(pin, pkthdr_ptr)) != NULL) {
while ((pktconst = safe_pcap_next(pin, pkthdr_ptr)) != NULL) {
packetnum++;
dbgx(2, "packet " COUNTER_SPEC " caplen %d", packetnum, pkthdr.caplen);

Expand Down