Blame SOURCES/libvirt-virbitmap-Refactor-virBitmapParse-to-avoid-access-beyond-bounds-of-array.patch

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