summaryrefslogtreecommitdiffstats
path: root/lib/libpcap/optimize.c
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2014-03-16 08:33:05 +0000
committerderaadt <deraadt@openbsd.org>2014-03-16 08:33:05 +0000
commit49639a4c85c00aa41ce01611c3084c0b06a6488e (patch)
treefaf2a4c499a2308f9b4db5f95a0557b6278f46a5 /lib/libpcap/optimize.c
parentsimplify ISPxxxx namings in Nd lines, ok kettenis jmc (diff)
downloadwireguard-openbsd-49639a4c85c00aa41ce01611c3084c0b06a6488e.tar.xz
wireguard-openbsd-49639a4c85c00aa41ce01611c3084c0b06a6488e.zip
Overflow check the calculation for a malloc size.
XXX noted by lteo, change proofed & tested as well
Diffstat (limited to 'lib/libpcap/optimize.c')
-rw-r--r--lib/libpcap/optimize.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/lib/libpcap/optimize.c b/lib/libpcap/optimize.c
index 1e52e89bfd4..add2fd9da84 100644
--- a/lib/libpcap/optimize.c
+++ b/lib/libpcap/optimize.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: optimize.c,v 1.13 2007/09/02 15:19:18 deraadt Exp $ */
+/* $OpenBSD: optimize.c,v 1.14 2014/03/16 08:33:05 deraadt Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <memory.h>
#include "pcap-int.h"
@@ -138,7 +139,8 @@ struct edge **edges;
static int nodewords;
static int edgewords;
struct block **levels;
-bpf_u_int32 *space;
+bpf_u_int32 *space1;
+bpf_u_int32 *space2;
#define BITS_PER_WORD (8*sizeof(bpf_u_int32))
/*
* True if a is in uset {p}
@@ -1715,7 +1717,8 @@ opt_cleanup()
free((void *)vnode_base);
free((void *)vmap);
free((void *)edges);
- free((void *)space);
+ free((void *)space1);
+ free((void *)space2);
free((void *)levels);
free((void *)blocks);
}
@@ -1799,6 +1802,7 @@ opt_init(root)
{
bpf_u_int32 *p;
int i, n, max_stmts;
+ size_t size1, size2;
/*
* First, count the blocks, so we can malloc an array to map
@@ -1829,13 +1833,39 @@ opt_init(root)
edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1;
nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
- /* XXX */
- space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space)
- + n_edges * edgewords * sizeof(*space));
- if (space == NULL)
+ size1 = 2;
+ if (n_blocks > SIZE_MAX / size1)
+ goto fail1;
+ size1 *= n_blocks;
+ if (nodewords > SIZE_MAX / size1)
+ goto fail1;
+ size1 *= nodewords;
+ if (sizeof(*space1) > SIZE_MAX / size1)
+ goto fail1;
+ size1 *= sizeof(*space1);
+
+ space1 = (bpf_u_int32 *)malloc(size1);
+ if (space1 == NULL) {
+fail1:
bpf_error("malloc");
+ }
+
+ size2 = n_edges;
+ if (edgewords > SIZE_MAX / size2)
+ goto fail2;
+ size2 *= edgewords;
+ if (sizeof(*space2) > SIZE_MAX / size2)
+ goto fail2;
+ size2 *= sizeof(*space2);
+
+ space2 = (bpf_u_int32 *)malloc(size2);
+ if (space2 == NULL) {
+fail2:
+ free(space1);
+ bpf_error("malloc");
+ }
- p = space;
+ p = space1;
all_dom_sets = p;
for (i = 0; i < n; ++i) {
blocks[i]->dom = p;
@@ -1846,6 +1876,7 @@ opt_init(root)
blocks[i]->closure = p;
p += nodewords;
}
+ p = space2;
all_edge_sets = p;
for (i = 0; i < n; ++i) {
register struct block *b = blocks[i];