|
|
cd6068 |
From 2ddd59f9e8a566227a8b5306c7fd5f0d641410b9 Mon Sep 17 00:00:00 2001
|
|
|
cd6068 |
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
|
cd6068 |
Date: Tue, 11 Feb 2014 20:08:43 +0000
|
|
|
cd6068 |
Subject: [PATCH] list-filesystems: Do not segfault if
|
|
|
cd6068 |
guestfs_btrfs_subvolume_list returns an error (RHBZ#1064008).
|
|
|
cd6068 |
|
|
|
cd6068 |
If calling guestfs_list_filesystems with a disk image containing a
|
|
|
cd6068 |
corrupt btrfs volume, the library would segfault. There was a missing
|
|
|
cd6068 |
check for a NULL return from guestfs_btrfs_subvolume_list.
|
|
|
cd6068 |
|
|
|
cd6068 |
This adds a check, returning the real error up through the stack and
|
|
|
cd6068 |
out of guestfs_list_filesystems.
|
|
|
cd6068 |
|
|
|
cd6068 |
This is potentially a denial of service if processing disk images from
|
|
|
cd6068 |
untrusted sources, but is not exploitable.
|
|
|
cd6068 |
|
|
|
cd6068 |
Thanks: Jeff Bastian for reporting the bug.
|
|
|
cd6068 |
(cherry picked from commit d70ceb4cbea165c960710576efac5a5716055486)
|
|
|
cd6068 |
---
|
|
|
cd6068 |
src/listfs.c | 34 +++++++++++++++++++++++-----------
|
|
|
cd6068 |
1 file changed, 23 insertions(+), 11 deletions(-)
|
|
|
cd6068 |
|
|
|
cd6068 |
diff --git a/src/listfs.c b/src/listfs.c
|
|
|
cd6068 |
index 9102c55..bbdb0a2 100644
|
|
|
cd6068 |
--- a/src/listfs.c
|
|
|
cd6068 |
+++ b/src/listfs.c
|
|
|
cd6068 |
@@ -39,7 +39,7 @@
|
|
|
cd6068 |
*/
|
|
|
cd6068 |
|
|
|
cd6068 |
static void remove_from_list (char **list, const char *item);
|
|
|
cd6068 |
-static void check_with_vfs_type (guestfs_h *g, const char *dev, struct stringsbuf *sb);
|
|
|
cd6068 |
+static int check_with_vfs_type (guestfs_h *g, const char *dev, struct stringsbuf *sb);
|
|
|
cd6068 |
static int is_mbr_partition_type_42 (guestfs_h *g, const char *partition);
|
|
|
cd6068 |
|
|
|
cd6068 |
char **
|
|
|
cd6068 |
@@ -78,17 +78,21 @@ guestfs__list_filesystems (guestfs_h *g)
|
|
|
cd6068 |
|
|
|
cd6068 |
/* Use vfs-type to check for filesystems on devices. */
|
|
|
cd6068 |
for (i = 0; devices[i] != NULL; ++i)
|
|
|
cd6068 |
- check_with_vfs_type (g, devices[i], &ret;;
|
|
|
cd6068 |
+ if (check_with_vfs_type (g, devices[i], &ret) == -1)
|
|
|
cd6068 |
+ goto error;
|
|
|
cd6068 |
|
|
|
cd6068 |
/* Use vfs-type to check for filesystems on partitions. */
|
|
|
cd6068 |
for (i = 0; partitions[i] != NULL; ++i) {
|
|
|
cd6068 |
- if (! is_mbr_partition_type_42 (g, partitions[i]))
|
|
|
cd6068 |
- check_with_vfs_type (g, partitions[i], &ret;;
|
|
|
cd6068 |
+ if (! is_mbr_partition_type_42 (g, partitions[i])) {
|
|
|
cd6068 |
+ if (check_with_vfs_type (g, partitions[i], &ret) == -1)
|
|
|
cd6068 |
+ goto error;
|
|
|
cd6068 |
+ }
|
|
|
cd6068 |
}
|
|
|
cd6068 |
|
|
|
cd6068 |
/* Use vfs-type to check for filesystems on md devices. */
|
|
|
cd6068 |
for (i = 0; mds[i] != NULL; ++i)
|
|
|
cd6068 |
- check_with_vfs_type (g, mds[i], &ret;;
|
|
|
cd6068 |
+ if (check_with_vfs_type (g, mds[i], &ret) == -1)
|
|
|
cd6068 |
+ goto error;
|
|
|
cd6068 |
|
|
|
cd6068 |
if (guestfs_feature_available (g, (char **) lvm2)) {
|
|
|
cd6068 |
/* Use vfs-type to check for filesystems on LVs. */
|
|
|
cd6068 |
@@ -96,7 +100,8 @@ guestfs__list_filesystems (guestfs_h *g)
|
|
|
cd6068 |
if (lvs == NULL) goto error;
|
|
|
cd6068 |
|
|
|
cd6068 |
for (i = 0; lvs[i] != NULL; ++i)
|
|
|
cd6068 |
- check_with_vfs_type (g, lvs[i], &ret;;
|
|
|
cd6068 |
+ if (check_with_vfs_type (g, lvs[i], &ret) == -1)
|
|
|
cd6068 |
+ goto error;
|
|
|
cd6068 |
}
|
|
|
cd6068 |
|
|
|
cd6068 |
if (guestfs_feature_available (g, (char **) ldm)) {
|
|
|
cd6068 |
@@ -105,13 +110,15 @@ guestfs__list_filesystems (guestfs_h *g)
|
|
|
cd6068 |
if (ldmvols == NULL) goto error;
|
|
|
cd6068 |
|
|
|
cd6068 |
for (i = 0; ldmvols[i] != NULL; ++i)
|
|
|
cd6068 |
- check_with_vfs_type (g, ldmvols[i], &ret;;
|
|
|
cd6068 |
+ if (check_with_vfs_type (g, ldmvols[i], &ret) == -1)
|
|
|
cd6068 |
+ goto error;
|
|
|
cd6068 |
|
|
|
cd6068 |
ldmparts = guestfs_list_ldm_partitions (g);
|
|
|
cd6068 |
if (ldmparts == NULL) goto error;
|
|
|
cd6068 |
|
|
|
cd6068 |
for (i = 0; ldmparts[i] != NULL; ++i)
|
|
|
cd6068 |
- check_with_vfs_type (g, ldmparts[i], &ret;;
|
|
|
cd6068 |
+ if (check_with_vfs_type (g, ldmparts[i], &ret) == -1)
|
|
|
cd6068 |
+ goto error;
|
|
|
cd6068 |
}
|
|
|
cd6068 |
|
|
|
cd6068 |
/* Finish off the list and return it. */
|
|
|
cd6068 |
@@ -143,7 +150,7 @@ remove_from_list (char **list, const char *item)
|
|
|
cd6068 |
* Apart from some types which we ignore, add the result to the
|
|
|
cd6068 |
* 'ret' string list.
|
|
|
cd6068 |
*/
|
|
|
cd6068 |
-static void
|
|
|
cd6068 |
+static int
|
|
|
cd6068 |
check_with_vfs_type (guestfs_h *g, const char *device, struct stringsbuf *sb)
|
|
|
cd6068 |
{
|
|
|
cd6068 |
const char *v;
|
|
|
cd6068 |
@@ -161,6 +168,9 @@ check_with_vfs_type (guestfs_h *g, const char *device, struct stringsbuf *sb)
|
|
|
cd6068 |
CLEANUP_FREE_BTRFSSUBVOLUME_LIST struct guestfs_btrfssubvolume_list *vols =
|
|
|
cd6068 |
guestfs_btrfs_subvolume_list (g, device);
|
|
|
cd6068 |
|
|
|
cd6068 |
+ if (vols == NULL)
|
|
|
cd6068 |
+ return -1;
|
|
|
cd6068 |
+
|
|
|
cd6068 |
for (size_t i = 0; i < vols->len; i++) {
|
|
|
cd6068 |
struct guestfs_btrfssubvolume *this = &vols->val[i];
|
|
|
cd6068 |
guestfs___add_sprintf (g, sb,
|
|
|
cd6068 |
@@ -178,17 +188,19 @@ check_with_vfs_type (guestfs_h *g, const char *device, struct stringsbuf *sb)
|
|
|
cd6068 |
*/
|
|
|
cd6068 |
size_t n = strlen (vfs_type);
|
|
|
cd6068 |
if (n >= 7 && STREQ (&vfs_type[n-7], "_member"))
|
|
|
cd6068 |
- return;
|
|
|
cd6068 |
+ return 0;
|
|
|
cd6068 |
|
|
|
cd6068 |
/* Ignore LUKS-encrypted partitions. These are also containers. */
|
|
|
cd6068 |
if (STREQ (vfs_type, "crypto_LUKS"))
|
|
|
cd6068 |
- return;
|
|
|
cd6068 |
+ return 0;
|
|
|
cd6068 |
|
|
|
cd6068 |
v = vfs_type;
|
|
|
cd6068 |
}
|
|
|
cd6068 |
|
|
|
cd6068 |
guestfs___add_string (g, sb, device);
|
|
|
cd6068 |
guestfs___add_string (g, sb, v);
|
|
|
cd6068 |
+
|
|
|
cd6068 |
+ return 0;
|
|
|
cd6068 |
}
|
|
|
cd6068 |
|
|
|
cd6068 |
/* We should ignore partitions that have MBR type byte 0x42, because
|
|
|
cd6068 |
--
|
|
|
cd6068 |
1.8.3.1
|
|
|
cd6068 |
|