]> xenbits.xensource.com Git - xen.git/commit
libelf: check all pointer accesses
authorIan Jackson <ian.jackson@eu.citrix.com>
Fri, 14 Jun 2013 15:45:38 +0000 (16:45 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Fri, 14 Jun 2013 15:45:38 +0000 (16:45 +0100)
commit39923542bb43e67776c4e8292d4a5a1adef2bd3b
treeba226e85816a69ccc08f353c20b3dc60a18149fd
parent8ce60b35beaac91a97b79c004ca6bf5d58e7390b
libelf: check all pointer accesses

We change the ELF_PTRVAL and ELF_HANDLE types and associated macros:

 * PTRVAL becomes a uintptr_t, for which we provide a typedef
   elf_ptrval.  This means no arithmetic done on it can overflow so
   the compiler cannot do any malicious invalid pointer arithmetic
   "optimisations".  It also means that any places where we
   dereference one of these pointers without using the appropriate
   macros or functions become a compilation error.

   So we can be sure that we won't miss any memory accesses.

   All the PTRVAL variables were previously void* or char*, so
   the actual address calculations are unchanged.

 * ELF_HANDLE becomes a union, one half of which keeps the pointer
   value and the other half of which is just there to record the
   type.

   The new type is not a pointer type so there can be no address
   calculations on it whose meaning would change.  Every assignment or
   access has to go through one of our macros.

 * The distinction between const and non-const pointers and char*s
   and void*s in libelf goes away.  This was not important (and
   anyway libelf tended to cast away const in various places).

 * The fields elf->image and elf->dest are renamed.  That proves
   that we haven't missed any unchecked uses of these actual
   pointer values.

 * The caller may fill in elf->caller_xdest_base and _size to
   specify another range of memory which is safe for libelf to
   access, besides the input and output images.

 * When accesses fail due to being out of range, we mark the elf
   "broken".  This will be checked and used for diagnostics in
   a following patch.

   We do not check for write accesses to the input image.  This is
   because libelf actually does this in a number of places.  So we
   simply permit that.

 * Each caller of libelf which used to set dest now sets
   dest_base and dest_size.

 * In xc_dom_load_elf_symtab we provide a new actual-pointer
   value hdr_ptr which we get from mapping the guest's kernel
   area and use (checking carefully) as the caller_xdest area.

 * The STAR(h) macro in libelf-dominfo.c now uses elf_access_unsigned.

 * elf-init uses the new elf_uval_3264 accessor to access the 32-bit
   fields, rather than an unchecked field access (ie, unchecked
   pointer access).

 * elf_uval has been reworked to use elf_uval_3264.  Both of these
   macros are essentially new in this patch (although they are derived
   from the old elf_uval) and need careful review.

 * ELF_ADVANCE_DEST is now safe in the sense that you can use it to
   chop parts off the front of the dest area but if you chop more than
   is available, the dest area is simply set to be empty, preventing
   future accesses.

 * We introduce some #defines for memcpy, memset, memmove and strcpy:
    - We provide elf_memcpy_safe and elf_memset_safe which take
      PTRVALs and do checking on the supplied pointers.
    - Users inside libelf must all be changed to either
      elf_mem*_unchecked (which are just like mem*), or
      elf_mem*_safe (which take PTRVALs) and are checked.  Any
      unchanged call sites become compilation errors.

 * We do _not_ at this time fix elf_access_unsigned so that it doesn't
   make unaligned accesses.  We hope that unaligned accesses are OK on
   every supported architecture.  But it does check the supplied
   pointer for validity.

This is part of the fix to a security issue, XSA-55.

Additional change in 4.1 backport:
* ELF_PRPTRVAL needs to be defined oddly on 4.1 and earlier because
  Xen's headers provide no definitions of uintptr_t or PRIuPTR.

Conflicts:
* Callers of elf_load_binary don't check its return value in 4.1.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
tools/libxc/xc_dom_elfloader.c
tools/libxc/xc_hvm_build.c
xen/arch/x86/domain_build.c
xen/common/libelf/libelf-dominfo.c
xen/common/libelf/libelf-loader.c
xen/common/libelf/libelf-private.h
xen/common/libelf/libelf-tools.c
xen/include/xen/libelf.h