fix overflow in opt_init
This commit is contained in:
parent
4d1cfc380a
commit
264d4df538
169
fix-optimize-add-a-bunch-of-overflow-checks.patch
Normal file
169
fix-optimize-add-a-bunch-of-overflow-checks.patch
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
From 119b90af867f3073c571ee333fd47dcd0dbccd3a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Guy Harris <gharris@sonic.net>
|
||||||
|
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
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
Name: libpcap
|
Name: libpcap
|
||||||
Epoch: 14
|
Epoch: 14
|
||||||
Version: 1.9.1
|
Version: 1.9.1
|
||||||
Release: 4
|
Release: 5
|
||||||
Summary: A system-independent interface for user-level packet capture
|
Summary: A system-independent interface for user-level packet capture
|
||||||
License: BSD with advertising
|
License: BSD with advertising
|
||||||
URL: http://www.tcpdump.org
|
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
|
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
|
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
|
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*
|
%{_mandir}/man*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue May 26 2020 gaihuiying <gaihuiying1@huawei.com> - 14:1.9.1-5
|
||||||
|
- Type:bugfix
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:fix overflow in opt_init
|
||||||
|
|
||||||
* Sat Jan 11 2020 openEuler Buildteam <buildteam@openeuler.org> - 14:1.9.1-4
|
* Sat Jan 11 2020 openEuler Buildteam <buildteam@openeuler.org> - 14:1.9.1-4
|
||||||
- delete useless info
|
- delete useless info
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user