Skip to content

Commit

Permalink
Merge pull request #593 from appneta/Bug_#571_max_packet_from_65549_t…
Browse files Browse the repository at this point in the history
…o_262144

Bug #571 max packet from 65549 to 262144
  • Loading branch information
fklassen committed Jun 2, 2020
2 parents 34b456d + 6b84b18 commit 00ef0e8
Show file tree
Hide file tree
Showing 10 changed files with 26 additions and 96 deletions.
3 changes: 2 additions & 1 deletion docs/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
- Fix warnings from gcc version 10 (#580)
- Heap Buffer Overflow in randomize_iparp (#579)
- Use after free in get_ipv6_next (#578)
- Heap Buffer Overflow in do_checksum (#577) (#556)
- Heap Buffer Overflow in git_ipv6_next (#576)
- Increase max snaplen to 262144 (#571)
- Heap Buffer Overflow in do_checksum (#556) (#577)

03/12/2019 Version 4.3.2
- CVE-2019-8381 memory access in do_checksum() (#538)
Expand Down
4 changes: 2 additions & 2 deletions src/common/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ u_char *_our_safe_pcap_next(pcap_t *pcap, struct pcap_pkthdr *pkthdr,
u_char *pktdata = (u_char *)pcap_next(pcap, pkthdr);

if (pktdata) {
if (pkthdr->len > MAXPACKET) {
if (pkthdr->len > MAX_SNAPLEN) {
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, MAXPACKET);
file, funcname, line, pkthdr->len, MAX_SNAPLEN);
exit(-1);
}

Expand Down
13 changes: 9 additions & 4 deletions src/defines.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,17 @@ typedef struct tcpr_speed_s {
#define MAX_FILES 1024 /* Max number of files we can pass to tcpreplay */

#define DEFAULT_MTU 1500 /* Max Transmission Unit of standard ethernet
* don't forget *frames* are MTU + L2 header! */
* don't forget *frames* are MTU + L2 header!
*/

#define MAXPACKET 65549 /* was 16436 linux loopback, but maybe something is bigger then
linux loopback */
#define MAX_SNAPLEN 262144 /* tell libpcap to capture the entire packet
* this is the maximum size supported by libpcap
* (https://github.com/the-tcpdump-group/libpcap/blob/master/pcap-int.h#L99-L125)
*/

#define MAX_SNAPLEN 65535 /* tell libpcap to capture the entire packet */
#define MAXPACKET (MAX_SNAPLEN + 22) /* snap length plus some room for adding a
* couple VLAN headers or a L2 header
*/

#define DNS_RESOLVE 1
#define DNS_DONT_RESOLVE 0
Expand Down
2 changes: 1 addition & 1 deletion src/tcpcapinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ main(int argc, char *argv[])
PRIx32".%"PRIx32,
pktcnt, pcap_ph.len, pcap_ph.caplen,
(unsigned int)pcap_ph.ts.tv_sec, (unsigned int)pcap_ph.ts.tv_usec);
if (pcap_fh.snaplen < pcap_ph.caplen) {
if (pcap_fh.snaplen < pcap_ph.caplen || pcap_ph.caplen > MAX_SNAPLEN) {
caplentoobig = 1;
}
caplen = pcap_ph.caplen;
Expand Down
82 changes: 0 additions & 82 deletions src/tcpedit/edit_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,88 +583,6 @@ untrunc_packet(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
return chksum;
}

/**
* Extracts the layer 7 data from the packet for TCP, UDP, ICMP
* returns the number of bytes and a pointer to the layer 7 data.
* Returns 0 for no data
*/
int
extract_data(tcpedit_t *tcpedit, const u_char *pktdata, int caplen,
char *l7data[])
{
int datalen = 0; /* amount of data beyond ip header */
ipv4_hdr_t *ip_hdr;
u_char ipbuff[MAXPACKET];
u_char *dataptr;
int ip_len;

assert(tcpedit);
assert(pktdata);
assert(l7data);

/* grab our IPv4 header */
dataptr = ipbuff;
if ((ip_hdr = (ipv4_hdr_t*)get_ipv4(pktdata, caplen,
tcpedit->runtime.dlt1, &dataptr)) == NULL)
return 0;

/*
* figure out the actual datalen which might be < the caplen
* due to ethernet padding
*/
ip_len = (int)ntohs(ip_hdr->ip_len);
if (caplen > ip_len) {
datalen = ip_len;
} else {
datalen = caplen - tcpedit->dlt_ctx->l2len;
}

/* update the datlen to not include the IP header len */
datalen -= ip_hdr->ip_hl << 2;
dataptr += ip_hdr->ip_hl << 2;
if (datalen <= 0)
goto nodata;

/* TCP ? */
if (ip_hdr->ip_p == IPPROTO_TCP) {
tcp_hdr_t *tcp_hdr = (tcp_hdr_t *) get_layer4_v4(ip_hdr, datalen);
datalen -= tcp_hdr->th_off << 2;
if (datalen <= 0)
goto nodata;

dataptr += tcp_hdr->th_off << 2;
}

/* UDP ? */
else if (ip_hdr->ip_p == IPPROTO_UDP) {
datalen -= TCPR_UDP_H;
if (datalen <= 0)
goto nodata;

dataptr += TCPR_UDP_H;
}

/* ICMP ? just ignore it for now */
else if (ip_hdr->ip_p == IPPROTO_ICMP) {
dbg(2, "Ignoring any possible data in ICMP packet");
goto nodata;
}

/* unknown proto, just dump everything past the IP header */
else {
dbg(2, "Unknown protocol, dumping everything past the IP header");
dataptr = (u_char *)ip_hdr;
}

dbgx(2, "packet had %d bytes of layer 7 data", datalen);
memcpy(l7data, dataptr, datalen);
return datalen;

nodata:
dbg(2, "packet has no data, skipping...");
return 0;
}

/**
* rewrites an IPv4 packet's TTL based on the rules
* return 0 if no change, 1 if changed
Expand Down
3 changes: 2 additions & 1 deletion src/tcpedit/plugins/dlt_hdlc/hdlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ dlt_hdlc_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, _U_ tcpr_dir_t di
hdlc_config_t *config = NULL;
hdlc_extra_t *extra = NULL;
tcpeditdlt_plugin_t *plugin = NULL;
u_char tmpbuff[MAXPACKET];
int newpktlen;

assert(ctx);
Expand All @@ -244,8 +243,10 @@ dlt_hdlc_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, _U_ tcpr_dir_t di
if (ctx->l2len > 4) {
memmove(packet + 4, packet + ctx->l2len, pktlen - ctx->l2len);
} else if (ctx->l2len < 4) {
u_char *tmpbuff = safe_malloc(pktlen);
memcpy(tmpbuff, packet, pktlen);
memcpy(packet + 4, (tmpbuff + ctx->l2len), pktlen - ctx->l2len);
safe_free(tmpbuff);
}

/* update the total packet length */
Expand Down
3 changes: 2 additions & 1 deletion src/tcpedit/plugins/dlt_user/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ dlt_user_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir)
{
user_config_t *config;
tcpeditdlt_plugin_t *plugin;
u_char tmpbuff[MAXPACKET];

assert(ctx);
assert(packet);
Expand All @@ -247,8 +246,10 @@ dlt_user_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir)
if (ctx->l2len > config->length) {
memmove(packet + config->length, packet + ctx->l2len, pktlen - ctx->l2len);
} else if (ctx->l2len < config->length) {
u_char *tmpbuff = safe_malloc(pktlen);
memcpy(tmpbuff, packet, pktlen);
memcpy(packet + config->length, (tmpbuff + ctx->l2len), pktlen - ctx->l2len);
safe_free(tmpbuff);
}

/* update the total packet length */
Expand Down
2 changes: 1 addition & 1 deletion src/tcpedit/tcpedit_opts.def
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ flag = {
value = m;
arg-type = number;
max = 1;
arg-range = "1->MAXPACKET";
arg-range = "1->MAX_SNAPLEN";
default = DEFAULT_MTU;
descrip = "Override default MTU length (1500 bytes)";
doc = <<- EOText
Expand Down
6 changes: 5 additions & 1 deletion src/tcpprep.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,14 @@ process_raw_packets(pcap_t * pcap)
const u_char *pktdata = NULL;
COUNTER packetnum = 0;
int l2len;
u_char ipbuff[MAXPACKET], *buffptr;
u_char *ipbuff, *buffptr;
tcpr_dir_t direction = TCPR_DIR_ERROR;
tcpprep_opt_t *options = tcpprep->options;

assert(pcap);

ipbuff = safe_malloc(MAXPACKET);

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

Expand Down Expand Up @@ -566,6 +568,8 @@ process_raw_packets(pcap_t * pcap)
#endif
}

safe_free(ipbuff);

return packetnum;
}

Expand Down
4 changes: 2 additions & 2 deletions src/tcprewrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ rewrite_packets(tcpedit_t *tcpedit, pcap_t *pin, pcap_dumper_t *pout)
packetnum++;
dbgx(2, "packet " COUNTER_SPEC " caplen %d", packetnum, pkthdr.caplen);

if (pkthdr.caplen > MAXPACKET)
errx(-1, "Frame too big, caplen %d exceeds %d", pkthdr.caplen, MAXPACKET);
if (pkthdr.caplen > MAX_SNAPLEN)
errx(-1, "Frame too big, caplen %d exceeds %d", pkthdr.caplen, MAX_SNAPLEN);
/*
* copy over the packet so we can pad it out if necessary and
* because pcap_next() returns a const ptr
Expand Down

0 comments on commit 00ef0e8

Please sign in to comment.