|
|
43fe83 |
From cfa44d1e04f4f32cdfd4098ec8a234fb784b4c9b Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <cfa44d1e04f4f32cdfd4098ec8a234fb784b4c9b.1377873640.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
43fe83 |
Date: Fri, 16 Aug 2013 15:30:58 +0200
|
|
|
43fe83 |
Subject: [PATCH] virbitmap: Refactor virBitmapParse to avoid access beyond
|
|
|
43fe83 |
bounds of array
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=997906 [7.0]
|
|
|
43fe83 |
|
|
|
43fe83 |
The virBitmapParse function was calling virBitmapIsSet() function that
|
|
|
43fe83 |
requires the caller to check the bounds of the bitmap without checking
|
|
|
43fe83 |
them. This resulted into crashes when parsing a bitmap string that was
|
|
|
43fe83 |
exceeding the bounds used as argument.
|
|
|
43fe83 |
|
|
|
43fe83 |
This patch refactors the function to use virBitmapSetBit without
|
|
|
43fe83 |
checking if the bit is set (this function does the checks internally)
|
|
|
43fe83 |
and then counts the bits in the bitmap afterwards (instead of keeping
|
|
|
43fe83 |
track while parsing the string).
|
|
|
43fe83 |
|
|
|
43fe83 |
This patch also changes the "parse_error" label to a more common
|
|
|
43fe83 |
"error".
|
|
|
43fe83 |
|
|
|
43fe83 |
The refactor should also get rid of the need to call sa_assert on the
|
|
|
43fe83 |
returned variable as the callpath should allow coverity to infer the
|
|
|
43fe83 |
possible return values.
|
|
|
43fe83 |
|
|
|
43fe83 |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=997367 [6.5]
|
|
|
43fe83 |
|
|
|
43fe83 |
Thanks to Alex Jia for tracking down the issue. This issue is introduced
|
|
|
43fe83 |
by commit 0fc8909.
|
|
|
43fe83 |
|
|
|
43fe83 |
(cherry picked from commit 47b9127e883677a0d60d767030a147450e919a25)
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/util/virbitmap.c | 38 +++++++++++++++-----------------------
|
|
|
43fe83 |
1 file changed, 15 insertions(+), 23 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
|
|
|
43fe83 |
index 7e1cd02..47c678e 100644
|
|
|
43fe83 |
--- a/src/util/virbitmap.c
|
|
|
43fe83 |
+++ b/src/util/virbitmap.c
|
|
|
43fe83 |
@@ -297,7 +297,6 @@ virBitmapParse(const char *str,
|
|
|
43fe83 |
virBitmapPtr *bitmap,
|
|
|
43fe83 |
size_t bitmapSize)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
- int ret = 0;
|
|
|
43fe83 |
bool neg = false;
|
|
|
43fe83 |
const char *cur;
|
|
|
43fe83 |
char *tmp;
|
|
|
43fe83 |
@@ -330,12 +329,12 @@ virBitmapParse(const char *str,
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
if (!c_isdigit(*cur))
|
|
|
43fe83 |
- goto parse_error;
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
|
|
|
43fe83 |
if (virStrToLong_i(cur, &tmp, 10, &start) < 0)
|
|
|
43fe83 |
- goto parse_error;
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
if (start < 0)
|
|
|
43fe83 |
- goto parse_error;
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
|
|
|
43fe83 |
cur = tmp;
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -343,35 +342,29 @@ virBitmapParse(const char *str,
|
|
|
43fe83 |
|
|
|
43fe83 |
if (*cur == ',' || *cur == 0 || *cur == terminator) {
|
|
|
43fe83 |
if (neg) {
|
|
|
43fe83 |
- if (virBitmapIsSet(*bitmap, start)) {
|
|
|
43fe83 |
- ignore_value(virBitmapClearBit(*bitmap, start));
|
|
|
43fe83 |
- ret--;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
+ if (virBitmapClearBit(*bitmap, start) < 0)
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
} else {
|
|
|
43fe83 |
- if (!virBitmapIsSet(*bitmap, start)) {
|
|
|
43fe83 |
- ignore_value(virBitmapSetBit(*bitmap, start));
|
|
|
43fe83 |
- ret++;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
+ if (virBitmapSetBit(*bitmap, start) < 0)
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
} else if (*cur == '-') {
|
|
|
43fe83 |
if (neg)
|
|
|
43fe83 |
- goto parse_error;
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
|
|
|
43fe83 |
cur++;
|
|
|
43fe83 |
virSkipSpaces(&cur);
|
|
|
43fe83 |
|
|
|
43fe83 |
if (virStrToLong_i(cur, &tmp, 10, &last) < 0)
|
|
|
43fe83 |
- goto parse_error;
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
if (last < start)
|
|
|
43fe83 |
- goto parse_error;
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
|
|
|
43fe83 |
cur = tmp;
|
|
|
43fe83 |
|
|
|
43fe83 |
for (i = start; i <= last; i++) {
|
|
|
43fe83 |
- if (!virBitmapIsSet(*bitmap, i)) {
|
|
|
43fe83 |
- ignore_value(virBitmapSetBit(*bitmap, i));
|
|
|
43fe83 |
- ret++;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
+ if (virBitmapSetBit(*bitmap, i) < 0)
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
virSkipSpaces(&cur);
|
|
|
43fe83 |
@@ -384,14 +377,13 @@ virBitmapParse(const char *str,
|
|
|
43fe83 |
} else if (*cur == 0 || *cur == terminator) {
|
|
|
43fe83 |
break;
|
|
|
43fe83 |
} else {
|
|
|
43fe83 |
- goto parse_error;
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
- sa_assert(ret >= 0);
|
|
|
43fe83 |
- return ret;
|
|
|
43fe83 |
+ return virBitmapCountBits(*bitmap);
|
|
|
43fe83 |
|
|
|
43fe83 |
-parse_error:
|
|
|
43fe83 |
+error:
|
|
|
43fe83 |
virBitmapFree(*bitmap);
|
|
|
43fe83 |
*bitmap = NULL;
|
|
|
43fe83 |
return -1;
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|