References: bnc#823011 XSA-55

From: Ian Jackson <ian.jackson@eu.citrix.com>
Date: Thu, 13 Jun 2013 19:10:14 +0100
Subject: [PATCH 12/21] libelf: use C99 bool for booleans

We want to remove uses of "int" because signed integers have
undesirable undefined behaviours on overflow.  Malicious compilers can
turn apparently-correct code into code with security vulnerabilities
etc.

In this patch we change all the booleans in libelf to C99 bool,
from <stdbool.h>.

For the one visible libelf boolean in libxc's public interface we
retain the use of int to avoid changing the ABI; libxc converts it to
a bool for consumption by libelf.

It is OK to change all values only ever used as booleans to _Bool
(bool) because conversion from any scalar type to a _Bool works the
same as the boolean test in if() or ?: and is always defined (C99
6.3.1.2).  But we do need to check that all these variables really are
only ever used that way.  (It is theoretically possible that the old
code truncated some 64-bit values to 32-bit ints which might become
zero depending on the value, which would mean a behavioural change in
this patch, but it seems implausible that treating 0x????????00000000
as false could have been intended.)

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

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

--- a/tools/libxc/xc_dom_elfloader.c
+++ b/tools/libxc/xc_dom_elfloader.c
@@ -51,7 +51,7 @@ static char *xc_dom_guest_type(struct xc
 /* ------------------------------------------------------------------------ */
 /* parse elf binary                                                         */
 
-static int check_elf_kernel(struct xc_dom_image *dom, int verbose)
+static int check_elf_kernel(struct xc_dom_image *dom, bool verbose)
 {
     if ( dom->kernel_blob == NULL )
     {
@@ -77,7 +77,7 @@ static int xc_dom_probe_elf_kernel(struc
 }
 
 static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
-                                  struct elf_binary *elf, int load)
+                                  struct elf_binary *elf, bool load)
 {
     struct elf_binary syms;
     ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr; ELF_HANDLE_DECL(elf_shdr) shdr2;
@@ -173,7 +173,7 @@ static int xc_dom_load_elf_symtab(struct
      */
 
     if ( xc_dom_logfile )
-        elf_set_logfile(&syms, xc_dom_logfile, 1);
+        elf_set_logfile(&syms, xc_dom_logfile, true);
 
     symtab = dom->bsd_symtab_start + sizeof(int);
     maxaddr = elf_round_up(&syms, symtab + elf_size(&syms, syms.ehdr) +
@@ -273,7 +273,7 @@ static int xc_dom_parse_elf_kernel(struc
     dom->private_loader = elf;
     rc = elf_init(elf, dom->kernel_blob, dom->kernel_size);
     if ( xc_dom_logfile )
-        elf_set_logfile(elf, xc_dom_logfile, 1);
+        elf_set_logfile(elf, xc_dom_logfile, true);
     if ( rc != 0 )
     {
         xc_dom_panic(XC_INVALID_KERNEL, "%s: corrupted ELF image\n",
--- a/xen/common/libelf/libelf-dominfo.c
+++ b/xen/common/libelf/libelf-dominfo.c
@@ -85,7 +85,7 @@ int elf_xen_parse_note(struct elf_binary
 /* *INDENT-OFF* */
     static const struct {
         char *name;
-        int str;
+        bool str;
     } note_desc[] = {
         [XEN_ELFNOTE_ENTRY] = { "ENTRY", 0},
         [XEN_ELFNOTE_HYPERCALL_PAGE] = { "HYPERCALL_PAGE", 0},
--- a/xen/common/libelf/libelf-loader.c
+++ b/xen/common/libelf/libelf-loader.c
@@ -74,7 +74,7 @@ int elf_init(struct elf_binary *elf, con
 }
 
 #ifndef __XEN__
-void elf_set_logfile(struct elf_binary *elf, FILE * log, int verbose)
+void elf_set_logfile(struct elf_binary *elf, FILE * log, bool verbose)
 {
     elf->log = log;
     elf->verbose = verbose;
@@ -82,7 +82,7 @@ void elf_set_logfile(struct elf_binary *
 #else
 void elf_set_verbose(struct elf_binary *elf)
 {
-    elf->verbose = 1;
+    elf->verbose = true;
 }
 #endif
 
--- a/xen/common/libelf/libelf-tools.c
+++ b/xen/common/libelf/libelf-tools.c
@@ -17,7 +17,7 @@ const char *elf_check_broken(const struc
     return elf->broken;
 }
 
-static int elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
+static bool elf_ptrval_in_range(elf_ptrval ptrval, uint64_t size,
                                const void *region, uint64_t regionsize)
     /*
      * Returns true if the putative memory area [ptrval,ptrval+size>
@@ -39,7 +39,7 @@ static int elf_ptrval_in_range(elf_ptrva
     return 1;
 }
 
-int elf_access_ok(struct elf_binary * elf,
+bool elf_access_ok(struct elf_binary * elf,
                   uint64_t ptrval, size_t size)
 {
     if ( elf_ptrval_in_range(ptrval, size, elf->image_base, elf->size) )
@@ -78,7 +78,7 @@ uint64_t elf_access_unsigned(struct elf_
                              uint64_t moreoffset, size_t size)
 {
     elf_ptrval ptrval = base + moreoffset;
-    int need_swap = elf_swap(elf);
+    bool need_swap = elf_swap(elf);
     const uint8_t *u8;
     const uint16_t *u16;
     const uint32_t *u32;
@@ -297,7 +297,7 @@ ELF_HANDLE_DECL(elf_note) elf_note_next(
 
 /* ------------------------------------------------------------------------ */
 
-int elf_is_elfbinary(const void *image_start, size_t image_size)
+bool elf_is_elfbinary(const void *image_start, size_t image_size)
 {
     const Elf32_Ehdr *ehdr = image_start;
 
@@ -307,7 +307,7 @@ int elf_is_elfbinary(const void *image_s
     return IS_ELF(*ehdr);
 }
 
-int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
+bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr)
 {
     uint64_t p_type = elf_uval(elf, phdr, p_type);
     uint64_t p_flags = elf_uval(elf, phdr, p_flags);
--- a/xen/include/xen/libelf.h
+++ b/xen/include/xen/libelf.h
@@ -29,6 +29,8 @@
 #error define architectural endianness
 #endif
 
+#include <stdbool.h>
+
 #undef ELFSIZE
 #include "elfstructs.h"
 #ifdef __XEN__
@@ -231,7 +233,7 @@ struct elf_binary {
     /* misc */
     FILE *log;
 #endif
-    int verbose;
+    bool verbose;
     const char *broken;
 };
 
@@ -295,8 +297,8 @@ void elf_memset_safe(struct elf_binary*,
    * outside permitted areas.
    */
 
-int elf_access_ok(struct elf_binary * elf,
-                  uint64_t ptrval, size_t size);
+bool elf_access_ok(struct elf_binary * elf,
+                   uint64_t ptrval, size_t size);
 
 #define elf_store_val(elf, type, ptr, val)                              \
     ({                                                                  \
@@ -343,9 +345,9 @@ uint64_t elf_note_numeric(struct elf_bin
 ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
 
 /* (Only) checks that the image has the right magic number. */
-int elf_is_elfbinary(const void *image_start, size_t image_size);
+bool elf_is_elfbinary(const void *image_start, size_t image_size);
 
-int elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
+bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
 
 /* ------------------------------------------------------------------------ */
 /* xc_libelf_loader.c                                                       */
@@ -358,7 +360,7 @@ int elf_init(struct elf_binary *elf, con
 #ifdef __XEN__
 void elf_set_verbose(struct elf_binary *elf);
 #else
-void elf_set_logfile(struct elf_binary *elf, FILE * log, int verbose);
+void elf_set_logfile(struct elf_binary *elf, FILE * log, bool verbose);
 #endif
 
 void elf_parse_binary(struct elf_binary *elf);
@@ -410,7 +412,7 @@ struct elf_dom_parms {
     char xen_ver[16];
     char loader[16];
     int pae;
-    int bsd_symtab;
+    bool bsd_symtab;
     uint64_t virt_base;
     uint64_t virt_entry;
     uint64_t virt_hypercall;
