!6 fix overflow in opt_init

Merge pull request !6 from lunankun/master
This commit is contained in:
openeuler-ci-bot 2020-08-11 15:26:42 +08:00 committed by Gitee
commit b0f5fd64c9
4 changed files with 419 additions and 4 deletions

View File

@ -0,0 +1,31 @@
From 3b9b6100912f7bb1ee43f9cfb51e804765a37bd4 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Thu, 3 Oct 2019 09:27:36 -0700
Subject: [PATCH 611/977] With MSVC, abort if _BitScanForward() returns 0.
It should never return zero, as never pass a value of 0 to
lowest_set_bit(), but this should keep Coverity from getting upset (as a
result of not understanding _BitScanForward() well enough to realize
that if it's passed a non-zero value it will never return 0).
Reported by Charles Smith at Tangible Security.
---
optimize.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/optimize.c b/optimize.c
index 283a6de..e38d2d7 100644
--- a/optimize.c
+++ b/optimize.c
@@ -137,7 +137,7 @@ lowest_set_bit(int mask)
* (It's currently not, in MSVC, even on 64-bit platforms, but....)
*/
if (_BitScanForward(&bit, (unsigned int)mask) == 0)
- return -1; /* mask is zero */
+ abort(); /* mask is zero */
return (int)bit;
}
#elif defined(MSDOS) && defined(__DJGPP__)
--
1.8.3.1

View File

@ -0,0 +1,279 @@
From d71913d38475f5b4f0dc753074337ba29d5c0789 Mon Sep 17 00:00:00 2001
From: Guy Harris <gharris@sonic.net>
Date: Thu, 21 May 2020 22:37:19 -0700
Subject: [PATCH 875/977] optimize: make some variables unsigned.
That should avoid some overflow failure modes, and allow saner overflow
checking.
---
optimize.c | 92 ++++++++++++++++++++++++++++++++++++++------------------------
1 file changed, 57 insertions(+), 35 deletions(-)
diff --git a/optimize.c b/optimize.c
index 325d4ff..bea8cdc 100644
--- a/optimize.c
+++ b/optimize.c
@@ -115,7 +115,7 @@ pcap_set_print_dot_graph(int value)
/*
* GCC 3.4 and later; we have __builtin_ctz().
*/
- #define lowest_set_bit(mask) __builtin_ctz(mask)
+ #define lowest_set_bit(mask) ((u_int)__builtin_ctz(mask))
#elif defined(_MSC_VER)
/*
* Visual Studio; we support only 2005 and later, so use
@@ -127,7 +127,7 @@ pcap_set_print_dot_graph(int value)
#pragma intrinsic(_BitScanForward)
#endif
-static __forceinline int
+static __forceinline u_int
lowest_set_bit(int mask)
{
unsigned long bit;
@@ -138,14 +138,14 @@ lowest_set_bit(int mask)
*/
if (_BitScanForward(&bit, (unsigned int)mask) == 0)
abort(); /* mask is zero */
- return (int)bit;
+ return (u_int)bit;
}
#elif defined(MSDOS) && defined(__DJGPP__)
/*
* MS-DOS with DJGPP, which declares ffs() in <string.h>, which
* we've already included.
*/
- #define lowest_set_bit(mask) (ffs((mask)) - 1)
+ #define lowest_set_bit(mask) ((u_int)(ffs((mask)) - 1))
#elif (defined(MSDOS) && defined(__WATCOMC__)) || defined(STRINGS_H_DECLARES_FFS)
/*
* MS-DOS with Watcom C, which has <strings.h> and declares ffs() there,
@@ -153,18 +153,18 @@ lowest_set_bit(int mask)
* of the Single UNIX Specification).
*/
#include <strings.h>
- #define lowest_set_bit(mask) (ffs((mask)) - 1)
+ #define lowest_set_bit(mask) (u_int)((ffs((mask)) - 1))
#else
/*
* None of the above.
* Use a perfect-hash-function-based function.
*/
-static int
+static u_int
lowest_set_bit(int mask)
{
unsigned int v = (unsigned int)mask;
- static const int MultiplyDeBruijnBitPosition[32] = {
+ static const u_int MultiplyDeBruijnBitPosition[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
@@ -257,17 +257,17 @@ typedef struct {
*/
int done;
- int n_blocks;
+ u_int n_blocks; /* number of blocks in the CFG; guaranteed to be > 0, as it's a RET instruction at a minimum */
struct block **blocks;
- int n_edges;
+ u_int n_edges; /* twice n_blocks, so guaranteed to be > 0 */
struct edge **edges;
/*
* A bit vector set representation of the dominators.
* We round up the set size to the next power of two.
*/
- int nodewords;
- int edgewords;
+ u_int nodewords; /* number of 32-bit words for a bit vector of "number of nodes" bits; guaranteed to be > 0 */
+ u_int edgewords; /* number of 32-bit words for a bit vector of "number of edges" bits; guaranteed to be > 0 */
struct block **levels;
bpf_u_int32 *space;
@@ -292,32 +292,35 @@ typedef struct {
/*
* a := a intersect b
+ * n must be guaranteed to be > 0
*/
#define SET_INTERSECT(a, b, n)\
{\
register bpf_u_int32 *_x = a, *_y = b;\
- register int _n = n;\
- while (--_n >= 0) *_x++ &= *_y++;\
+ register u_int _n = n;\
+ do *_x++ &= *_y++; while (--_n != 0);\
}
/*
* a := a - b
+ * n must be guaranteed to be > 0
*/
#define SET_SUBTRACT(a, b, n)\
{\
register bpf_u_int32 *_x = a, *_y = b;\
- register int _n = n;\
- while (--_n >= 0) *_x++ &=~ *_y++;\
+ register u_int _n = n;\
+ do *_x++ &=~ *_y++; while (--_n != 0);\
}
/*
* a := a union b
+ * n must be guaranteed to be > 0
*/
#define SET_UNION(a, b, n)\
{\
register bpf_u_int32 *_x = a, *_y = b;\
- register int _n = n;\
- while (--_n >= 0) *_x++ |= *_y++;\
+ register u_int _n = n;\
+ do *_x++ |= *_y++; while (--_n != 0);\
}
uset all_dom_sets;
@@ -414,7 +417,8 @@ find_levels(opt_state_t *opt_state, struct icode *ic)
static void
find_dom(opt_state_t *opt_state, struct block *root)
{
- int i;
+ u_int i;
+ int level;
struct block *b;
bpf_u_int32 *x;
@@ -422,16 +426,25 @@ find_dom(opt_state_t *opt_state, struct block *root)
* Initialize sets to contain all nodes.
*/
x = opt_state->all_dom_sets;
+ /*
+ * These are both guaranteed to be > 0, so the product is
+ * guaranteed to be > 0.
+ *
+ * XXX - but what if it overflows?
+ */
i = opt_state->n_blocks * opt_state->nodewords;
- while (--i >= 0)
+ do
*x++ = 0xFFFFFFFFU;
+ while (--i != 0);
/* Root starts off empty. */
- for (i = opt_state->nodewords; --i >= 0;)
+ i = opt_state->nodewords;
+ do
root->dom[i] = 0;
+ while (--i != 0);
/* root->level is the highest level no found. */
- for (i = root->level; i >= 0; --i) {
- for (b = opt_state->levels[i]; b; b = b->link) {
+ for (level = root->level; level >= 0; --level) {
+ for (b = opt_state->levels[level]; b; b = b->link) {
SET_INSERT(b->dom, b->id);
if (JT(b) == 0)
continue;
@@ -458,19 +471,28 @@ propedom(opt_state_t *opt_state, struct edge *ep)
static void
find_edom(opt_state_t *opt_state, struct block *root)
{
- int i;
+ u_int i;
uset x;
+ int level;
struct block *b;
x = opt_state->all_edge_sets;
- for (i = opt_state->n_edges * opt_state->edgewords; --i >= 0; )
+ /*
+ * These are both guaranteed to be > 0, so the product is
+ * guaranteed to be > 0.
+ *
+ * XXX - but what if it overflows?
+ */
+ i = opt_state->n_edges * opt_state->edgewords;
+ do
x[i] = 0xFFFFFFFFU;
+ while (--i != 0);
/* root->level is the highest level no found. */
memset(root->et.edom, 0, opt_state->edgewords * sizeof(*(uset)0));
memset(root->ef.edom, 0, opt_state->edgewords * sizeof(*(uset)0));
- for (i = root->level; i >= 0; --i) {
- for (b = opt_state->levels[i]; b != 0; b = b->link) {
+ for (level = root->level; level >= 0; --level) {
+ for (b = opt_state->levels[level]; b != 0; b = b->link) {
propedom(opt_state, &b->et);
propedom(opt_state, &b->ef);
}
@@ -487,7 +509,7 @@ find_edom(opt_state_t *opt_state, struct block *root)
static void
find_closure(opt_state_t *opt_state, struct block *root)
{
- int i;
+ int level;
struct block *b;
/*
@@ -497,8 +519,8 @@ find_closure(opt_state_t *opt_state, struct block *root)
opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->all_closure_sets));
/* root->level is the highest level no found. */
- for (i = root->level; i >= 0; --i) {
- for (b = opt_state->levels[i]; b; b = b->link) {
+ for (level = root->level; level >= 0; --level) {
+ for (b = opt_state->levels[level]; b; b = b->link) {
SET_INSERT(b->closure, b->id);
if (JT(b) == 0)
continue;
@@ -1674,6 +1696,6 @@ fold_edge(struct block *child, struct edge *ep)
static void
opt_j(opt_state_t *opt_state, struct edge *ep)
{
- register int i, k;
+ register u_int i, k;
register struct block *target;
@@ -2116,17 +2138,16 @@ link_inedge(struct edge *parent, struct block *child)
static void
find_inedges(opt_state_t *opt_state, struct block *root)
{
- int i;
struct block *b;
- for (i = 0; i < opt_state->n_blocks; ++i)
+ for (u_int i = 0; i < opt_state->n_blocks; ++i)
opt_state->blocks[i]->in_edges = 0;
/*
* Traverse the graph, adding each edge to the predecessor
* list of its successors. Skip the leaves (i.e. level 0).
*/
- for (i = root->level; i > 0; --i) {
+ for (int i = root->level; i > 0; --i) {
for (b = opt_state->levels[i]; b != 0; b = b->link) {
link_inedge(&b->et, JT(b));
link_inedge(&b->ef, JF(b));
@@ -2336,7 +2357,7 @@ static void
intern_blocks(opt_state_t *opt_state, struct icode *ic)
{
struct block *p;
- int i, j;
+ u_int i, j;
int done1; /* don't shadow global */
top:
done1 = 1;
@@ -2345,7 +2366,8 @@ intern_blocks(opt_state_t *opt_state, struct icode *ic)
mark_code(ic);
- for (i = opt_state->n_blocks - 1; --i >= 0; ) {
+ for (i = opt_state->n_blocks - 1; i != 0; ) {
+ --i;
if (!isMarked(ic, opt_state->blocks[i]))
continue;
for (j = i + 1; j < opt_state->n_blocks; ++j) {
--
1.8.3.1

View File

@ -0,0 +1,96 @@
From 2aa7d268e2ce37025d68a3f428001f6f779f56e8 Mon Sep 17 00:00:00 2001
From: Guy Harris <gharris@sonic.net>
Date: Thu, 21 May 2020 23:36:09 -0700
Subject: [PATCH 876/977] optimize: fix some of those changes.
For loops with predecrements that we eliminated because we don't want to
rely on the loop index going negative if it's zero before the
predecrement - the index is now unsigned, so it'll *never go negative -
we revert to a similar loop, but with the test checking whether the
index is 0 and decrementing it as the first action in the loop body.
(Yeah, it means that, on machines with condition codes, you don't get to
use the condition code setting of the decrement "for free"; we'll let
the compiler and the processor figure out how to do that efficiently.)
---
optimize.c | 35 ++++++++++++++++-------------------
1 file changed, 16 insertions(+), 19 deletions(-)
diff --git a/optimize.c b/optimize.c
index bea8cdc..07fc0f3 100644
--- a/optimize.c
+++ b/optimize.c
@@ -427,20 +427,18 @@ find_dom(opt_state_t *opt_state, struct block *root)
*/
x = opt_state->all_dom_sets;
/*
- * These are both guaranteed to be > 0, so the product is
- * guaranteed to be > 0.
- *
- * XXX - but what if it overflows?
+ * XXX - what if the multiplication overflows?
*/
i = opt_state->n_blocks * opt_state->nodewords;
- do
+ while (i != 0) {
+ --i;
*x++ = 0xFFFFFFFFU;
- while (--i != 0);
+ }
/* Root starts off empty. */
- i = opt_state->nodewords;
- do
+ for (i = opt_state->nodewords; i != 0;) {
+ --i;
root->dom[i] = 0;
- while (--i != 0);
+ }
/* root->level is the highest level no found. */
for (level = root->level; level >= 0; --level) {
@@ -478,15 +476,12 @@ find_edom(opt_state_t *opt_state, struct block *root)
x = opt_state->all_edge_sets;
/*
- * These are both guaranteed to be > 0, so the product is
- * guaranteed to be > 0.
- *
- * XXX - but what if it overflows?
+ * XXX - what if the multiplication overflows?
*/
- i = opt_state->n_edges * opt_state->edgewords;
- do
+ for (i = opt_state->n_edges * opt_state->edgewords; i != 0; ) {
+ --i;
x[i] = 0xFFFFFFFFU;
- while (--i != 0);
+ }
/* root->level is the highest level no found. */
memset(root->et.edom, 0, opt_state->edgewords * sizeof(*(uset)0));
@@ -2138,17 +2133,19 @@ link_inedge(struct edge *parent, struct block *child)
static void
find_inedges(opt_state_t *opt_state, struct block *root)
{
+ u_int i;
+ int level;
struct block *b;
- for (u_int i = 0; i < opt_state->n_blocks; ++i)
+ for (i = 0; i < opt_state->n_blocks; ++i)
opt_state->blocks[i]->in_edges = 0;
/*
* Traverse the graph, adding each edge to the predecessor
* list of its successors. Skip the leaves (i.e. level 0).
*/
- for (int i = root->level; i > 0; --i) {
- for (b = opt_state->levels[i]; b != 0; b = b->link) {
+ for (level = root->level; level > 0; --level) {
+ for (b = opt_state->levels[level]; b != 0; b = b->link) {
link_inedge(&b->et, JT(b));
link_inedge(&b->ef, JF(b));
}
--
1.8.3.1

View File

@ -1,15 +1,18 @@
Name: libpcap Name: libpcap
Epoch: 14 Epoch: 14
Version: 1.9.1 Version: 1.9.1
Release: 5 Release: 6
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
Source0: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz Source0: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz
Patch0001: 0003-pcap-linux-apparently-ctc-interfaces-on-s390-has-eth.patch Patch0: 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 Patch1: clean-up-signed-vs-unsigned-do-more-error-checking-in-the-parser.patch
Patch0003: fix-optimize-add-a-bunch-of-overflow-checks.patch Patch2: fix-optimize-add-a-bunch-of-overflow-checks.patch
Patch3: 0611-With-MSVC-abort-if-_BitScanForward-returns-0.patch
Patch4: 0875-optimize-make-some-variables-unsigned.patch
Patch5: 0876-optimize-fix-some-of-those-changes.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
@ -60,6 +63,12 @@ export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
%{_mandir}/man* %{_mandir}/man*
%changelog %changelog
* Fri Aug 07 2020 lunankun <lunankun@huawei.com> - 14:1.9.1-6
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:fix overflow in opt_init
* Tue May 26 2020 gaihuiying <gaihuiying1@huawei.com> - 14:1.9.1-5 * Tue May 26 2020 gaihuiying <gaihuiying1@huawei.com> - 14:1.9.1-5
- Type:bugfix - Type:bugfix
- ID:NA - ID:NA