[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xen-users
Subject:    [Xen-users] Xen Security Advisory 194 (CVE-2016-9384) - guest 32-bit ELF symbol table load leaking h
From:       Xen.org security team <security () xen ! org>
Date:       2016-11-22 12:02:30
Message-ID: E1c99mQ-00087x-6f () xenbits ! xenproject ! org
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

            Xen Security Advisory CVE-2016-9384 / XSA-194
                              version 3

           guest 32-bit ELF symbol table load leaking host data

UPDATES IN VERSION 3
====================

Public release.

ISSUE DESCRIPTION
=================

Along with their main kernel binary, unprivileged guests may arrange
to have their Xen environment load (kernel) symbol tables for their
use.  The ELF image metadata created for this purpose has a few unused
bytes when the symbol table binary is in 32-bit ELF format.  These
unused bytes were not properly cleared during symbol table loading.

IMPACT
======

A malicious unprivileged guest may be able to obtain sensitive
information from the host.

The information leak is small and not under the control of the guest,
so effectively exploiting this vulnerability is probably difficult.

VULNERABLE SYSTEMS
==================

Only Xen version 4.7 is affected.  Xen versions 4.6 and earlier are not
affected.

The vulnerability is not exposed to x86 HVM guests, unless the host
toolstack has configured to load the guest with a non-default loader,
rather than hvmloader.

MITIGATION
==========

There is no known mitigation.

CREDITS
=======

This issue was discovered by Roger Pau Monné of Citrix.

RESOLUTION
==========

Applying the attached patch resolves this issue.

xsa194.patch           xen-unstable, Xen 4.7.x

$ sha256sum xsa194*
4dad65417d9ff3c86e763d3c88cf8de79b58a9981d531f641ae0dd0dcedce911  xsa194.patch
$

DEPLOYMENT DURING EMBARGO
=========================

Deployment of the patches and/or mitigations described above (or
others which are substantially similar) is permitted during the
embargo, even on public-facing systems with untrusted guest users and
administrators.

But: Distribution of updated software is prohibited (except to other
members of the predisclosure list).

Predisclosure list members who wish to deploy significantly different
patches and/or mitigations, please contact the Xen Project Security
Team.

(Note: this during-embargo deployment notice is retained in
post-embargo publicly released Xen Project advisories, even though it
is then no longer applicable.  This is to enable the community to have
oversight of the Xen Project Security Team's decisionmaking.)

For more information about permissible uses of embargoed information,
consult the Xen Project community's agreed Security Policy:
  http://www.xenproject.org/security-policy.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAEBAgAGBQJYNDLYAAoJEIP+FMlX6CvZqAoH/39GSWwDpYnflz3TcFyQUViM
j36XzzStWya71ewaXiguUbTHHg6mK47pK4EA/3zFwerczz/5yQzhlToitPkP/8WE
5Qbg9Wyg4STylzeKaiTvLzqUK6XSiJ4oKZwLsnU7tFPLcb6FBMm9t3bzg9NECaft
/6zYj1SVCvoLJB/gtgbwrz2MCjVZQZ9Q2+mpirvu0ePQRD73M0cwfj1ncqjUkFd9
ZNdk14gmxOk1/wWAm/oD1QKUWmjpzByT5dbGcMV3OxGs1V2Px+o4c1u1t/agldr0
wC2LvCK9IED9JcBaH/M85TTAGR7GqfU8l9x3ep97GkrUpquX4OGFt7na28M1YUQ=
=Gc8O
-----END PGP SIGNATURE-----

["xsa194.patch" (application/octet-stream)]

From 71096b016f7fd54a72af73576948cb25cf42ebcb Mon Sep 17 00:00:00 2001
From: Roger Pau Monné <roger.pau@citrix.com>Date: Wed, 2 Nov 2016 15:02:00 +0000
Subject: [PATCH] libelf: fix stack memory leak when loading 32 bit symbol
 tables

The 32 bit Elf structs are smaller than the 64 bit ones, which means that
when loading them there's some padding left uninitialized at the end of each
struct (because the size indicated in e_ehsize and e_shentsize is
smaller than the size of elf_ehdr and elf_shdr).

Fix this by introducing a new helper that is used to set
[caller_]xdest_{base/size} and that takes care of performing the appropriate
memset of the region. This newly introduced helper is then used to set and
unset xdest_{base/size} in elf_load_bsdsyms. Now that the full struct
is zeroed, there's no need to specifically zero the undefined section.

This is XSA-194.

Suggested-by: Ian Jackson <ian.jackson@eu.citrix.com>

Also remove the open coded (and redundant with the earlier
elf_memset_unchecked()) use of caller_xdest_* from elf_init().

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
---
 xen/common/libelf/libelf-loader.c | 14 +++-----------
 xen/common/libelf/libelf-tools.c  | 11 +++++++++--
 xen/include/xen/libelf.h          | 15 +++++++++------
 3 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
index 4d3ae4d..bc1f87b 100644
--- a/xen/common/libelf/libelf-loader.c
+++ b/xen/common/libelf/libelf-loader.c
@@ -43,8 +43,6 @@ elf_errorstatus elf_init(struct elf_binary *elf, const char *image_input, size_t
     elf->ehdr = ELF_MAKE_HANDLE(elf_ehdr, (elf_ptrval)image_input);
     elf->class = elf_uval_3264(elf, elf->ehdr, e32.e_ident[EI_CLASS]);
     elf->data = elf_uval_3264(elf, elf->ehdr, e32.e_ident[EI_DATA]);
-    elf->caller_xdest_base = NULL;
-    elf->caller_xdest_size = 0;
 
     /* Sanity check phdr. */
     offset = elf_uval(elf, elf->ehdr, e_phoff) +
@@ -284,9 +282,8 @@ do {                                                                \
 #define SYMTAB_INDEX    1
 #define STRTAB_INDEX    2
 
-    /* Allow elf_memcpy_safe to write to symbol_header. */
-    elf->caller_xdest_base = &header;
-    elf->caller_xdest_size = sizeof(header);
+    /* Allow elf_memcpy_safe to write to header. */
+    elf_set_xdest(elf, &header, sizeof(header));
 
     /*
      * Calculate the position of the various elements in GUEST MEMORY SPACE.
@@ -319,11 +316,7 @@ do {                                                                \
     elf_store_field_bitness(elf, header_handle, e_phentsize, 0);
     elf_store_field_bitness(elf, header_handle, e_phnum, 0);
 
-    /* Zero the undefined section. */
-    section_handle = ELF_MAKE_HANDLE(elf_shdr,
-                     ELF_REALPTR2PTRVAL(&header.elf_header.section[SHN_UNDEF]));
     shdr_size = elf_uval(elf, elf->ehdr, e_shentsize);
-    elf_memset_safe(elf, ELF_HANDLE_PTRVAL(section_handle), 0, shdr_size);
 
     /*
      * The symtab section header is going to reside in section[SYMTAB_INDEX],
@@ -404,8 +397,7 @@ do {                                                                \
     }
 
     /* Remove permissions from elf_memcpy_safe. */
-    elf->caller_xdest_base = NULL;
-    elf->caller_xdest_size = 0;
+    elf_set_xdest(elf, NULL, 0);
 
 #undef SYMTAB_INDEX
 #undef STRTAB_INDEX
diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
index 5a4757b..e73e729 100644
--- a/xen/common/libelf/libelf-tools.c
+++ b/xen/common/libelf/libelf-tools.c
@@ -59,8 +59,7 @@ bool elf_access_ok(struct elf_binary * elf,
         return 1;
     if ( elf_ptrval_in_range(ptrval, size, elf->dest_base, elf->dest_size) )
         return 1;
-    if ( elf_ptrval_in_range(ptrval, size,
-                             elf->caller_xdest_base, elf->caller_xdest_size) )
+    if ( elf_ptrval_in_range(ptrval, size, elf->xdest_base, elf->xdest_size) )
         return 1;
     elf_mark_broken(elf, "out of range access");
     return 0;
@@ -373,6 +372,14 @@ bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr
     return ((p_type == PT_LOAD) && (p_flags & (PF_R | PF_W | PF_X)) != 0);
 }
 
+void elf_set_xdest(struct elf_binary *elf, void *addr, uint64_t size)
+{
+    elf->xdest_base = addr;
+    elf->xdest_size = size;
+    if ( addr != NULL )
+        elf_memset_safe(elf, ELF_REALPTR2PTRVAL(addr), 0, size);
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
index 95b5370..cf62bc7 100644
--- a/xen/include/xen/libelf.h
+++ b/xen/include/xen/libelf.h
@@ -210,13 +210,11 @@ struct elf_binary {
     uint64_t bsd_symtab_pend;
 
     /*
-     * caller's other acceptable destination
-     *
-     * Again, these are trusted and must be valid (or 0) so long
-     * as the struct elf_binary is in use.
+     * caller's other acceptable destination.
+     * Set by elf_set_xdest.  Do not set these directly.
      */
-    void *caller_xdest_base;
-    uint64_t caller_xdest_size;
+    void *xdest_base;
+    uint64_t xdest_size;
 
 #ifndef __XEN__
     /* misc */
@@ -494,5 +492,10 @@ static inline void ELF_ADVANCE_DEST(struct elf_binary *elf, uint64_t amount)
     }
 }
 
+/* Specify a (single) additional destination, to which the image may
+ * cause writes.  As with dest_base and dest_size, the values provided
+ * are trusted and must be valid so long as the struct elf_binary
+ * is in use or until elf_set_xdest(,0,0) is called. */
+void elf_set_xdest(struct elf_binary *elf, void *addr, uint64_t size);
 
 #endif /* __XEN_LIBELF_H__ */
-- 
2.1.4


[Attachment #4 (text/plain)]

_______________________________________________
Xen-users mailing list
Xen-users@lists.xen.org
https://lists.xen.org/xen-users

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic