CVE-2013-2124: Other (NVD-CWE-Other)
value: Double free vulnerability in inspect-fs.c in LibguestFS 1.20.x before 1.20.7, 1.21.x, 1.22.0, and 1.23.0 allows remote attackers to cause a denial of service (crash) via empty guest files.
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
Published: 2014-05-27T14:55Z
Repository: https://github.com/libguestfs/libguestfs
Language: C
Files changed: src/inspect-fs.c
Commit date: 2013-05-28 16:20:09 +0100
Commit message: inspection: Fix double-free when certain guest files are empty.

The following commit:

  commit 5a3da366268825b26b470cde35658b67c1d11cd4
  Author: Richard W.M. Jones <rjones@redhat.com>
  Date:   Thu Jan 24 17:07:38 2013 +0000

      inspect: Use CLEANUP_* macros in inspection code.

can cause a double-free along an error path when certain guest files
are empty where we expected those files to contain at least one line.

This causes virt-inspector to crash when run on these guests.

The following is a test case which demonstrates the crash.
`f20rawhidex64' is a Fedora guest, but with small adjustments to the
test you could use any Linux guest for this test.

  $ qemu-img create -f qcow2 -b f20rawhidex64 /tmp/test.qcow2
  Formatting '/tmp/test.qcow2', fmt=qcow2 size=21474836480 backing_file='f20rawhidex64' encryption=off cluster_size=65536 lazy_refcounts=off
  $ guestfish -i -a /tmp/test.qcow2 -- rm /etc/redhat-release : touch /etc/redhat-release
  $ virt-inspector /tmp/test.qcow2
  *** glibc detected *** virt-inspector: double free or corruption (fasttop): 0x00007f18bc9925a0 ***
  ======= Backtrace: =========
  /lib64/libc.so.6(+0x34ecc7ca8e)[0x7f18b8e64a8e]
  /lib64/libguestfs.so.0(+0x3f91898078)[0x7f18ba13c078]
  /lib64/libguestfs.so.0(+0x3f91899761)[0x7f18ba13d761]
  /lib64/libguestfs.so.0(+0x3f91896d12)[0x7f18ba13ad12]
  /lib64/libguestfs.so.0(+0x3f91894140)[0x7f18ba138140]
  /lib64/libguestfs.so.0(guestfs_inspect_os+0x35)[0x7f18ba0bcc35]
  virt-inspector(main+0x547)[0x7f18ba7c57d7]
  /lib64/libc.so.6(__libc_start_main+0xf5)[0x7f18b8e09a05]
  virt-inspector(+0x6665)[0x7f18ba7c7665]

This is a denial of service, but not likely to be exploitable.

(Found by Coverity)

Diff: diff --git a/src/inspect-fs.c b/src/inspect-fs.c
index a8dc05cb..5ca17254 100644
--- a/src/inspect-fs.c
+++ b/src/inspect-fs.c
@@ -542,11 +542,11 @@ guestfs___check_package_management (guestfs_h *g, struct inspect_fs *fs)
  * will usually need to check for this case.
  */
 char *
 guestfs___first_line_of_file (guestfs_h *g, const char *filename)
 {
-  CLEANUP_FREE char **lines = NULL; /* sic: not CLEANUP_FREE_STRING_LIST */
+  char **lines = NULL; /* sic: not CLEANUP_FREE_STRING_LIST */
   int64_t size;
   char *ret;
 
   /* Don't trust guestfs_head_n not to break with very large files.
    * Check the file size is something reasonable first.
@@ -571,10 +571,12 @@ guestfs___first_line_of_file (guestfs_h *g, const char *filename)
   }
   /* lines[1] should be NULL because of '1' argument above ... */
 
   ret = lines[0];               /* caller frees */
 
+  free (lines);
+
   return ret;
 }
 
 /* Get the first matching line (using egrep [-i]) of a small file,
  * without any trailing newline character.

Vulnerable code:   CLEANUP_FREE char **lines = NULL; /* sic: not CLEANUP_FREE_STRING_LIST */
Fixed code:   char **lines = NULL; /* sic: not CLEANUP_FREE_STRING_LIST */
  free (lines);