diff options
| author | 2014-03-16 08:33:05 +0000 | |
|---|---|---|
| committer | 2014-03-16 08:33:05 +0000 | |
| commit | 49639a4c85c00aa41ce01611c3084c0b06a6488e (patch) | |
| tree | faf2a4c499a2308f9b4db5f95a0557b6278f46a5 /lib/libpcap/optimize.c | |
| parent | simplify ISPxxxx namings in Nd lines, ok kettenis jmc (diff) | |
| download | wireguard-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.c | 47 |
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]; |
