diff --git a/fix-optimize-add-a-bunch-of-overflow-checks.patch b/fix-optimize-add-a-bunch-of-overflow-checks.patch new file mode 100644 index 0000000000000000000000000000000000000000..9c56c81d38c16ed1f12abf4103cc4290c88f46d0 --- /dev/null +++ b/fix-optimize-add-a-bunch-of-overflow-checks.patch @@ -0,0 +1,169 @@ +From 119b90af867f3073c571ee333fd47dcd0dbccd3a Mon Sep 17 00:00:00 2001 +From: Guy Harris +Date: Fri, 22 May 2020 01:20:45 -0700 +Subject: [PATCH] optimize: add a bunch of overflow checks. + +This should address GitHub issue #929; it picks up checks from GitHub +pull request #930, and adds some more. + +Also, make some more values unsigned. +--- + gencode.h | 4 +-- + optimize.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 76 insertions(+), 10 deletions(-) + +diff --git a/gencode.h b/gencode.h +index dc099f5..053e85f 100644 +--- a/gencode.h ++++ b/gencode.h +@@ -240,7 +240,7 @@ typedef bpf_u_int32 *uset; + #define N_ATOMS (BPF_MEMWORDS+2) + + struct edge { +- int id; ++ u_int id; + int code; + uset edom; + struct block *succ; +@@ -254,7 +254,7 @@ struct edge { + }; + + struct block { +- int id; ++ u_int id; + struct slist *stmts; /* side effect stmts */ + struct stmt s; /* branch stmt */ + int mark; +diff --git a/optimize.c b/optimize.c +index 07fc0f3..18fbe70 100644 +--- a/optimize.c ++++ b/optimize.c +@@ -2457,13 +2459,19 @@ count_blocks(struct icode *ic, struct block *p) + static void + number_blks_r(opt_state_t *opt_state, struct icode *ic, struct block *p) + { +- int n; ++ u_int n; + + if (p == 0 || isMarked(ic, p)) + return; + + Mark(ic, p); + n = opt_state->n_blocks++; ++ if (opt_state->n_blocks == 0) { ++ /* ++ * Overflow. ++ */ ++ opt_error(opt_state, "filter is too complex to optimize"); ++ } + p->id = n; + opt_state->blocks[n] = p; + +@@ -2511,6 +2519,8 @@ opt_init(opt_state_t *opt_state, struct icode *ic) + { + bpf_u_int32 *p; + int i, n, max_stmts; ++ u_int product; ++ size_t block_memsize, edge_memsize; + + /* + * First, count the blocks, so we can malloc an array to map +@@ -2526,6 +2536,12 @@ opt_init(opt_state_t *opt_state, struct icode *ic) + number_blks_r(opt_state, ic, ic->root); + + opt_state->n_edges = 2 * opt_state->n_blocks; ++ if ((opt_state->n_edges / 2) != opt_state->n_blocks) { ++ /* ++ * Overflow. ++ */ ++ opt_error(opt_state, "filter is too complex to optimize"); ++ } + opt_state->edges = (struct edge **)calloc(opt_state->n_edges, sizeof(*opt_state->edges)); + if (opt_state->edges == NULL) { + opt_error(opt_state, "malloc"); +@@ -2542,9 +2558,59 @@ opt_init(opt_state_t *opt_state, struct icode *ic) + opt_state->edgewords = opt_state->n_edges / (8 * sizeof(bpf_u_int32)) + 1; + opt_state->nodewords = opt_state->n_blocks / (8 * sizeof(bpf_u_int32)) + 1; + ++ /* ++ * Make sure opt_state->n_blocks * opt_state->nodewords fits ++ * in a u_int; we use it as a u_int number-of-iterations ++ * value. ++ */ ++ product = opt_state->n_blocks * opt_state->nodewords; ++ if ((product / opt_state->n_blocks) != opt_state->nodewords) { ++ /* ++ * XXX - just punt and don't try to optimize? ++ * In practice, this is unlikely to happen with ++ * a normal filter. ++ */ ++ opt_error(opt_state, "filter is too complex to optimize"); ++ } ++ ++ /* ++ * Make sure the total memory required for that doesn't ++ * overflow. ++ */ ++ block_memsize = (size_t)2 * product * sizeof(*opt_state->space); ++ if ((block_memsize / product) != 2 * sizeof(*opt_state->space)) { ++ opt_error(opt_state, "filter is too complex to optimize"); ++ } ++ ++ /* ++ * Make sure opt_state->n_edges * opt_state->edgewords fits ++ * in a u_int; we use it as a u_int number-of-iterations ++ * value. ++ */ ++ product = opt_state->n_edges * opt_state->edgewords; ++ if ((product / opt_state->n_edges) != opt_state->edgewords) { ++ opt_error(opt_state, "filter is too complex to optimize"); ++ } ++ ++ /* ++ * Make sure the total memory required for that doesn't ++ * overflow. ++ */ ++ edge_memsize = (size_t)product * sizeof(*opt_state->space); ++ if (edge_memsize / product != sizeof(*opt_state->space)) { ++ opt_error(opt_state, "filter is too complex to optimize"); ++ } ++ ++ /* ++ * Make sure the total memory required for both of them dosn't ++ * overflow. ++ */ ++ if (block_memsize > SIZE_MAX - edge_memsize) { ++ opt_error(opt_state, "filter is too complex to optimize"); ++ } ++ + /* XXX */ +- opt_state->space = (bpf_u_int32 *)malloc(2 * opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->space) +- + opt_state->n_edges * opt_state->edgewords * sizeof(*opt_state->space)); ++ opt_state->space = (bpf_u_int32 *)malloc(block_memsize + edge_memsize); + if (opt_state->space == NULL) { + opt_error(opt_state, "malloc"); + } +@@ -2920,7 +2986,7 @@ dot_dump_node(struct icode *ic, struct block *block, struct bpf_program *prog, + icount = slength(block->stmts) + 1 + block->longjt + block->longjf; + noffset = min(block->offset + icount, (int)prog->bf_len); + +- fprintf(out, "\tblock%d [shape=ellipse, id=\"block-%d\" label=\"BLOCK%d\\n", block->id, block->id, block->id); ++ fprintf(out, "\tblock%u [shape=ellipse, id=\"block-%u\" label=\"BLOCK%u\\n", block->id, block->id, block->id); + for (i = block->offset; i < noffset; i++) { + fprintf(out, "\\n%s", bpf_image(prog->bf_insns + i, i)); + } +@@ -2947,9 +3013,9 @@ dot_dump_edge(struct icode *ic, struct block *block, FILE *out) + Mark(ic, block); + + if (JT(block)) { +- fprintf(out, "\t\"block%d\":se -> \"block%d\":n [label=\"T\"]; \n", ++ fprintf(out, "\t\"block%u\":se -> \"block%u\":n [label=\"T\"]; \n", + block->id, JT(block)->id); +- fprintf(out, "\t\"block%d\":sw -> \"block%d\":n [label=\"F\"]; \n", ++ fprintf(out, "\t\"block%u\":sw -> \"block%u\":n [label=\"F\"]; \n", + block->id, JF(block)->id); + } + dot_dump_edge(ic, JT(block), out); +-- +1.8.3.1 + diff --git a/libpcap.spec b/libpcap.spec index b71ea63c3d9c4776cd8e4f993d9f5d1371b87d0f..61d674337ff138aedacf3c8c873b330478d2e361 100644 --- a/libpcap.spec +++ b/libpcap.spec @@ -1,7 +1,7 @@ Name: libpcap Epoch: 14 Version: 1.9.1 -Release: 4 +Release: 5 Summary: A system-independent interface for user-level packet capture License: BSD with advertising URL: http://www.tcpdump.org @@ -9,6 +9,7 @@ Source0: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz Patch0001: 0003-pcap-linux-apparently-ctc-interfaces-on-s390-has-eth.patch Patch0002: clean-up-signed-vs-unsigned-do-more-error-checking-in-the-parser.patch +Patch0003: fix-optimize-add-a-bunch-of-overflow-checks.patch BuildRequires: bison bluez-libs-devel flex gcc git glibc-kernheaders >= 2.2.0 @@ -59,6 +60,12 @@ export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" %{_mandir}/man* %changelog +* Tue May 26 2020 gaihuiying - 14:1.9.1-5 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:fix overflow in opt_init + * Sat Jan 11 2020 openEuler Buildteam - 14:1.9.1-4 - delete useless info