qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 2/3] qemu-img: Detect backing file chain infinite


From: Stefan Hajnoczi
Subject: [Qemu-devel] [PATCH v2 2/3] qemu-img: Detect backing file chain infinite loops
Date: Mon, 15 Oct 2012 14:44:16 +0200

A malicious or corruption image can contain an infinite loop of backing
files.  The qemu-img info --backing-chain command must not hang when
such files are encountered.

Signed-off-by: Stefan Hajnoczi <address@hidden>
---
 qemu-img.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/qemu-img.c b/qemu-img.c
index c717f3e..60a5cc8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1259,6 +1259,11 @@ typedef enum OutputFormat {
     OFORMAT_HUMAN,
 } OutputFormat;
 
+static gboolean str_equal_func(gconstpointer a, gconstpointer b)
+{
+    return strcmp(a, b) == 0;
+}
+
 static int img_info(int argc, char **argv)
 {
     int c;
@@ -1268,6 +1273,7 @@ static int img_info(int argc, char **argv)
     char *filename, *fmt;
     BlockDriverState *bs;
     ImageInfo *info;
+    GHashTable *filenames;
 
     fmt = NULL;
     output = NULL;
@@ -1306,6 +1312,9 @@ static int img_info(int argc, char **argv)
     }
     filename = g_strdup(argv[optind++]);
 
+    filenames = g_hash_table_new_full(g_str_hash, str_equal_func,
+                                      g_free, NULL);
+
     if (output && !strcmp(output, "json")) {
         output_format = OFORMAT_JSON;
     } else if (output && !strcmp(output, "human")) {
@@ -1320,6 +1329,12 @@ static int img_info(int argc, char **argv)
     }
 
     do {
+        if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
+            error_report("Aborting due to backing file chain infinite loop.");
+            goto err;
+        }
+        g_hash_table_insert(filenames, g_strdup(filename), NULL);
+
         bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
                            false);
         if (!bs) {
@@ -1376,11 +1391,13 @@ static int img_info(int argc, char **argv)
     if (chain && output_format == OFORMAT_JSON) {
         printf("]\n");
     }
+    g_hash_table_destroy(filenames);
     return 0;
 
 err:
     g_free(filename);
     g_free(fmt);
+    g_hash_table_destroy(filenames);
     return 1;
 }
 
-- 
1.7.11.7




reply via email to

[Prev in Thread] Current Thread [Next in Thread]