1c5bb4e
From 86e39ce58e91fe55d4fdbc914cb1955c45acc20e Mon Sep 17 00:00:00 2001
e2ce63b
From: Ian Jackson <ian.jackson@eu.citrix.com>
1c5bb4e
Date: Fri, 14 Jun 2013 16:45:39 +0100
1c5bb4e
Subject: [PATCH 13/21] libelf: use only unsigned integers
e2ce63b
e2ce63b
Signed integers have undesirable undefined behaviours on overflow.
e2ce63b
Malicious compilers can turn apparently-correct code into code with
e2ce63b
security vulnerabilities etc.
e2ce63b
e2ce63b
So use only unsigned integers.  Exceptions are booleans (which we have
e2ce63b
already changed) and error codes.
e2ce63b
e2ce63b
We _do_ change all the chars which aren't fixed constants from our own
e2ce63b
text segment, but not the char*s.  This is because it is safe to
e2ce63b
access an arbitrary byte through a char*, but not necessarily safe to
e2ce63b
convert an arbitrary value to a char.
e2ce63b
e2ce63b
As a consequence we need to compile libelf with -Wno-pointer-sign.
e2ce63b
e2ce63b
It is OK to change all the signed integers to unsigned because all the
e2ce63b
inequalities in libelf are in contexts where we don't "expect"
e2ce63b
negative numbers.
e2ce63b
e2ce63b
In libelf-dominfo.c:elf_xen_parse we rename a variable "rc" to
e2ce63b
"more_notes" as it actually contains a note count derived from the
e2ce63b
input image.  The "error" return value from elf_xen_parse_notes is
e2ce63b
changed from -1 to ~0U.
e2ce63b
e2ce63b
grepping shows only one occurrence of "PRId" or "%d" or "%ld" in
e2ce63b
libelf and xc_dom_elfloader.c (a "%d" which becomes "%u").
e2ce63b
1c5bb4e
This is part of the fix to a security issue, XSA-55.
1c5bb4e
1c5bb4e
Conflicts in 4.1 series:
1c5bb4e
 * xc_dom_load_elf_kernel has no rc variable to change.
1c5bb4e
 * elf_load_image doesn't exist.
1c5bb4e
e2ce63b
For those concerned about unintentional functional changes, the
e2ce63b
following rune produces a version of the patch which is much smaller
e2ce63b
and eliminates only non-functional changes:
e2ce63b
e2ce63b
 GIT_EXTERNAL_DIFF=.../unsigned-differ git-diff <before>..<after>
e2ce63b
e2ce63b
where <before> and <after> are git refs for the code before and after
e2ce63b
this patch, and unsigned-differ is this shell script:
e2ce63b
e2ce63b
    #!/bin/bash
e2ce63b
    set -e
e2ce63b
e2ce63b
    seddery () {
e2ce63b
            perl -pe 's/\b(?:elf_errorstatus|elf_negerrnoval)\b/int/g'
e2ce63b
    }
e2ce63b
e2ce63b
    path="$1"
e2ce63b
    in="$2"
e2ce63b
    out="$5"
e2ce63b
e2ce63b
    set +e
e2ce63b
    diff -pu --label "$path~" <(seddery <"$in") --label "$path" <(seddery <"$out")
e2ce63b
    rc=$?
e2ce63b
    set -e
e2ce63b
    if [ $rc = 1 ]; then rc=0; fi
e2ce63b
    exit $rc
e2ce63b
e2ce63b
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
e2ce63b
---
e2ce63b
 tools/libxc/Makefile               |    9 +++++-
e2ce63b
 tools/libxc/xc_dom.h               |    7 +++--
1c5bb4e
 tools/libxc/xc_dom_elfloader.c     |   40 +++++++++++++++------------
1c5bb4e
 tools/xcutils/readnotes.c          |   15 +++++-----
e2ce63b
 xen/common/libelf/Makefile         |    2 +
1c5bb4e
 xen/common/libelf/libelf-dominfo.c |   52 ++++++++++++++++++-----------------
e2ce63b
 xen/common/libelf/libelf-loader.c  |   12 ++++----
1c5bb4e
 xen/common/libelf/libelf-tools.c   |   22 +++++++-------
1c5bb4e
 xen/include/xen/libelf.h           |   19 +++++++-----
1c5bb4e
 9 files changed, 98 insertions(+), 80 deletions(-)
e2ce63b
e2ce63b
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
e2ce63b
index 6f5c307..139b791 100644
e2ce63b
--- a/tools/libxc/Makefile
e2ce63b
+++ b/tools/libxc/Makefile
e2ce63b
@@ -49,8 +49,13 @@ GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
e2ce63b
 vpath %.c ../../xen/common/libelf
e2ce63b
 CFLAGS += -I../../xen/common/libelf
e2ce63b
 
e2ce63b
-GUEST_SRCS-y += libelf-tools.c libelf-loader.c
e2ce63b
-GUEST_SRCS-y += libelf-dominfo.c
e2ce63b
+ELF_SRCS-y += libelf-tools.c libelf-loader.c
e2ce63b
+ELF_SRCS-y += libelf-dominfo.c
e2ce63b
+
e2ce63b
+GUEST_SRCS-y += $(ELF_SRCS-y)
e2ce63b
+
e2ce63b
+$(patsubst %.c,%.o,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
e2ce63b
+$(patsubst %.c,%.opic,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
e2ce63b
 
e2ce63b
 # new domain builder
e2ce63b
 GUEST_SRCS-y                 += xc_dom_core.c xc_dom_boot.c
e2ce63b
diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
1c5bb4e
index 6b118ad..9dffbe6 100644
e2ce63b
--- a/tools/libxc/xc_dom.h
e2ce63b
+++ b/tools/libxc/xc_dom.h
e2ce63b
@@ -135,9 +135,10 @@ struct xc_dom_image {
e2ce63b
 
e2ce63b
 struct xc_dom_loader {
e2ce63b
     char *name;
e2ce63b
-    int (*probe) (struct xc_dom_image * dom);
e2ce63b
-    int (*parser) (struct xc_dom_image * dom);
e2ce63b
-    int (*loader) (struct xc_dom_image * dom);
e2ce63b
+    /* Sadly the error returns from these functions are not consistent: */
e2ce63b
+    elf_negerrnoval (*probe) (struct xc_dom_image * dom);
e2ce63b
+    elf_negerrnoval (*parser) (struct xc_dom_image * dom);
e2ce63b
+    elf_errorstatus (*loader) (struct xc_dom_image * dom);
e2ce63b
 
e2ce63b
     struct xc_dom_loader *next;
e2ce63b
 };
e2ce63b
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
1c5bb4e
index c3da5b9..77b2e5b 100644
e2ce63b
--- a/tools/libxc/xc_dom_elfloader.c
e2ce63b
+++ b/tools/libxc/xc_dom_elfloader.c
e2ce63b
@@ -84,7 +84,7 @@ static char *xc_dom_guest_type(struct xc_dom_image *dom,
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 /* parse elf binary                                                         */
e2ce63b
 
e2ce63b
-static int check_elf_kernel(struct xc_dom_image *dom, bool verbose)
e2ce63b
+static elf_negerrnoval check_elf_kernel(struct xc_dom_image *dom, bool verbose)
e2ce63b
 {
e2ce63b
     if ( dom->kernel_blob == NULL )
e2ce63b
     {
e2ce63b
@@ -106,12 +106,12 @@ static int check_elf_kernel(struct xc_dom_image *dom, bool verbose)
e2ce63b
     return 0;
e2ce63b
 }
e2ce63b
 
e2ce63b
-static int xc_dom_probe_elf_kernel(struct xc_dom_image *dom)
e2ce63b
+static elf_negerrnoval xc_dom_probe_elf_kernel(struct xc_dom_image *dom)
e2ce63b
 {
e2ce63b
     return check_elf_kernel(dom, 0);
e2ce63b
 }
e2ce63b
 
e2ce63b
-static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
e2ce63b
+static elf_errorstatus xc_dom_load_elf_symtab(struct xc_dom_image *dom,
e2ce63b
                                   struct elf_binary *elf, bool load)
e2ce63b
 {
e2ce63b
     struct elf_binary syms;
e2ce63b
@@ -119,7 +119,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
e2ce63b
     xen_vaddr_t symtab, maxaddr;
e2ce63b
     ELF_PTRVAL_CHAR hdr;
e2ce63b
     size_t size;
e2ce63b
-    int h, count, type, i, tables = 0;
e2ce63b
+    unsigned h, count, type, i, tables = 0;
e2ce63b
 
e2ce63b
     if ( elf_swap(elf) )
1c5bb4e
     {
1c5bb4e
@@ -140,13 +140,13 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
1c5bb4e
         elf->caller_xdest_base = hdr_ptr;
1c5bb4e
         elf->caller_xdest_size = allow_size;
e2ce63b
         hdr = ELF_REALPTR2PTRVAL(hdr_ptr);
e2ce63b
-        elf_store_val(elf, int, hdr, size - sizeof(int));
e2ce63b
+        elf_store_val(elf, unsigned, hdr, size - sizeof(unsigned));
e2ce63b
     }
e2ce63b
     else
e2ce63b
     {
e2ce63b
         char *hdr_ptr;
e2ce63b
 
e2ce63b
-        size = sizeof(int) + elf_size(elf, elf->ehdr) +
e2ce63b
+        size = sizeof(unsigned) + elf_size(elf, elf->ehdr) +
e2ce63b
             elf_shdr_count(elf) * elf_size(elf, shdr);
e2ce63b
         hdr_ptr = xc_dom_malloc(dom, size);
e2ce63b
         if ( hdr_ptr == NULL )
1c5bb4e
@@ -157,15 +157,15 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
e2ce63b
         dom->bsd_symtab_start = elf_round_up(elf, dom->kernel_seg.vend);
e2ce63b
     }
e2ce63b
 
e2ce63b
-    elf_memcpy_safe(elf, hdr + sizeof(int),
e2ce63b
+    elf_memcpy_safe(elf, hdr + sizeof(unsigned),
e2ce63b
            ELF_IMAGE_BASE(elf),
e2ce63b
            elf_size(elf, elf->ehdr));
e2ce63b
-    elf_memcpy_safe(elf, hdr + sizeof(int) + elf_size(elf, elf->ehdr),
e2ce63b
+    elf_memcpy_safe(elf, hdr + sizeof(unsigned) + elf_size(elf, elf->ehdr),
e2ce63b
            ELF_IMAGE_BASE(elf) + elf_uval(elf, elf->ehdr, e_shoff),
e2ce63b
            elf_shdr_count(elf) * elf_size(elf, shdr));
e2ce63b
     if ( elf_64bit(elf) )
e2ce63b
     {
e2ce63b
-        Elf64_Ehdr *ehdr = (Elf64_Ehdr *)(hdr + sizeof(int));
e2ce63b
+        Elf64_Ehdr *ehdr = (Elf64_Ehdr *)(hdr + sizeof(unsigned));
e2ce63b
         ehdr->e_phoff = 0;
e2ce63b
         ehdr->e_phentsize = 0;
e2ce63b
         ehdr->e_phnum = 0;
1c5bb4e
@@ -174,22 +174,22 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
e2ce63b
     }
e2ce63b
     else
e2ce63b
     {
e2ce63b
-        Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(hdr + sizeof(int));
e2ce63b
+        Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(hdr + sizeof(unsigned));
e2ce63b
         ehdr->e_phoff = 0;
e2ce63b
         ehdr->e_phentsize = 0;
e2ce63b
         ehdr->e_phnum = 0;
e2ce63b
         ehdr->e_shoff = elf_size(elf, elf->ehdr);
e2ce63b
         ehdr->e_shstrndx = SHN_UNDEF;
e2ce63b
     }
e2ce63b
-    if ( elf->caller_xdest_size < sizeof(int) )
e2ce63b
+    if ( elf->caller_xdest_size < sizeof(unsigned) )
e2ce63b
     {
e2ce63b
         DOMPRINTF("%s/%s: header size %"PRIx64" too small",
e2ce63b
                   __FUNCTION__, load ? "load" : "parse",
e2ce63b
                   (uint64_t)elf->caller_xdest_size);
e2ce63b
         return -1;
e2ce63b
     }
e2ce63b
-    if ( elf_init(&syms, elf->caller_xdest_base + sizeof(int),
e2ce63b
-                  elf->caller_xdest_size - sizeof(int)) )
e2ce63b
+    if ( elf_init(&syms, elf->caller_xdest_base + sizeof(unsigned),
e2ce63b
+                  elf->caller_xdest_size - sizeof(unsigned)) )
e2ce63b
         return -1;
e2ce63b
 
e2ce63b
     /*
1c5bb4e
@@ -209,7 +209,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
e2ce63b
 
e2ce63b
     xc_elf_set_logfile(dom->xch, &syms, 1);
e2ce63b
 
e2ce63b
-    symtab = dom->bsd_symtab_start + sizeof(int);
e2ce63b
+    symtab = dom->bsd_symtab_start + sizeof(unsigned);
e2ce63b
     maxaddr = elf_round_up(&syms, symtab + elf_size(&syms, syms.ehdr) +
e2ce63b
                            elf_shdr_count(&syms) * elf_size(&syms, shdr));
e2ce63b
 
1c5bb4e
@@ -255,7 +255,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
e2ce63b
             size = elf_uval(&syms, shdr, sh_size);
e2ce63b
             maxaddr = elf_round_up(&syms, maxaddr + size);
e2ce63b
             tables++;
e2ce63b
-            DOMPRINTF("%s: h=%d %s, size=0x%zx, maxaddr=0x%" PRIx64 "",
e2ce63b
+            DOMPRINTF("%s: h=%u %s, size=0x%zx, maxaddr=0x%" PRIx64 "",
e2ce63b
                       __FUNCTION__, h,
e2ce63b
                       type == SHT_SYMTAB ? "symtab" : "strtab",
e2ce63b
                       size, maxaddr);
1c5bb4e
@@ -294,10 +294,14 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
e2ce63b
     return 0;
e2ce63b
 }
e2ce63b
 
e2ce63b
-static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
e2ce63b
+static elf_errorstatus xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
e2ce63b
+    /*
e2ce63b
+     * This function sometimes returns -1 for error and sometimes
1c5bb4e
+     * an errno value.  ?!?!
e2ce63b
+     */
e2ce63b
 {
e2ce63b
     struct elf_binary *elf;
e2ce63b
-    int rc;
e2ce63b
+    elf_errorstatus rc;
e2ce63b
 
e2ce63b
     rc = check_elf_kernel(dom, 1);
e2ce63b
     if ( rc != 0 )
1c5bb4e
@@ -350,7 +354,7 @@ out:
e2ce63b
     return rc;
e2ce63b
 }
e2ce63b
 
e2ce63b
-static int xc_dom_load_elf_kernel(struct xc_dom_image *dom)
e2ce63b
+static elf_errorstatus xc_dom_load_elf_kernel(struct xc_dom_image *dom)
e2ce63b
 {
e2ce63b
     struct elf_binary *elf = dom->private_loader;
e2ce63b
     xen_pfn_t pages;
e2ce63b
diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
1c5bb4e
index b940a36..543e0f5 100644
e2ce63b
--- a/tools/xcutils/readnotes.c
e2ce63b
+++ b/tools/xcutils/readnotes.c
e2ce63b
@@ -28,7 +28,7 @@ static void print_numeric_note(const char *prefix, struct elf_binary *elf,
e2ce63b
 			       ELF_HANDLE_DECL(elf_note) note)
e2ce63b
 {
e2ce63b
 	uint64_t value = elf_note_numeric(elf, note);
e2ce63b
-	int descsz = elf_uval(elf, note, descsz);
e2ce63b
+	unsigned descsz = elf_uval(elf, note, descsz);
e2ce63b
 
e2ce63b
 	printf("%s: %#*" PRIx64 " (%d bytes)\n",
e2ce63b
 	       prefix, 2+2*descsz, value, descsz);
e2ce63b
@@ -37,7 +37,7 @@ static void print_numeric_note(const char *prefix, struct elf_binary *elf,
e2ce63b
 static void print_l1_mfn_valid_note(const char *prefix, struct elf_binary *elf,
e2ce63b
 				    ELF_HANDLE_DECL(elf_note) note)
e2ce63b
 {
e2ce63b
-	int descsz = elf_uval(elf, note, descsz);
e2ce63b
+	unsigned descsz = elf_uval(elf, note, descsz);
e2ce63b
 	ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
e2ce63b
 
e2ce63b
 	/* XXX should be able to cope with a list of values. */
e2ce63b
@@ -57,10 +57,10 @@ static void print_l1_mfn_valid_note(const char *prefix, struct elf_binary *elf,
e2ce63b
 
e2ce63b
 }
e2ce63b
 
e2ce63b
-static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start, ELF_HANDLE_DECL(elf_note) end)
e2ce63b
+static unsigned print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start, ELF_HANDLE_DECL(elf_note) end)
e2ce63b
 {
e2ce63b
 	ELF_HANDLE_DECL(elf_note) note;
e2ce63b
-	int notes_found = 0;
e2ce63b
+	unsigned notes_found = 0;
e2ce63b
 	const char *this_note_name;
e2ce63b
 
e2ce63b
 	for ( note = start; ELF_HANDLE_PTRVAL(note) < ELF_HANDLE_PTRVAL(end); note = elf_note_next(elf, note) )
1c5bb4e
@@ -119,7 +119,7 @@ static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start,
e2ce63b
 			break;
e2ce63b
 		default:
e2ce63b
 			printf("unknown note type %#x\n",
e2ce63b
-			       (int)elf_uval(elf, note, type));
e2ce63b
+			       (unsigned)elf_uval(elf, note, type));
e2ce63b
 			break;
e2ce63b
 		}
e2ce63b
 	}
1c5bb4e
@@ -129,12 +129,13 @@ static int print_notes(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) start,
e2ce63b
 int main(int argc, char **argv)
e2ce63b
 {
e2ce63b
 	const char *f;
e2ce63b
-	int fd,h,size,usize,count;
e2ce63b
+	int fd;
e2ce63b
+	unsigned h,size,usize,count;
e2ce63b
 	void *image,*tmp;
e2ce63b
 	struct stat st;
e2ce63b
 	struct elf_binary elf;
e2ce63b
 	ELF_HANDLE_DECL(elf_shdr) shdr;
e2ce63b
-	int notes_found = 0;
e2ce63b
+	unsigned notes_found = 0;
e2ce63b
 
e2ce63b
 	if (argc != 2)
e2ce63b
 	{
e2ce63b
diff --git a/xen/common/libelf/Makefile b/xen/common/libelf/Makefile
e2ce63b
index 854e738..e788705 100644
e2ce63b
--- a/xen/common/libelf/Makefile
e2ce63b
+++ b/xen/common/libelf/Makefile
e2ce63b
@@ -2,6 +2,8 @@ obj-y := libelf.o
e2ce63b
 
e2ce63b
 SECTIONS := text data rodata $(foreach n,1 2 4 8,rodata.str1.$(n)) $(foreach r,rel rel.ro,data.$(r) data.$(r).local)
e2ce63b
 
e2ce63b
+CFLAGS += -Wno-pointer-sign
e2ce63b
+
e2ce63b
 libelf.o: libelf-temp.o Makefile
e2ce63b
 	$(OBJCOPY) $(foreach s,$(SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@
e2ce63b
 
e2ce63b
diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c
1c5bb4e
index 3a0db85..6054e40 100644
e2ce63b
--- a/xen/common/libelf/libelf-dominfo.c
e2ce63b
+++ b/xen/common/libelf/libelf-dominfo.c
e2ce63b
@@ -28,15 +28,15 @@ static const char *const elf_xen_feature_names[] = {
e2ce63b
     [XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel",
e2ce63b
     [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb"
e2ce63b
 };
e2ce63b
-static const int elf_xen_features =
e2ce63b
+static const unsigned elf_xen_features =
e2ce63b
 sizeof(elf_xen_feature_names) / sizeof(elf_xen_feature_names[0]);
e2ce63b
 
e2ce63b
-int elf_xen_parse_features(const char *features,
e2ce63b
+elf_errorstatus elf_xen_parse_features(const char *features,
e2ce63b
                            uint32_t *supported,
e2ce63b
                            uint32_t *required)
e2ce63b
 {
e2ce63b
-    char feature[64];
e2ce63b
-    int pos, len, i;
e2ce63b
+    unsigned char feature[64];
e2ce63b
+    unsigned pos, len, i;
e2ce63b
 
e2ce63b
     if ( features == NULL )
e2ce63b
         return 0;
e2ce63b
@@ -92,7 +92,7 @@ int elf_xen_parse_features(const char *features,
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 /* xen elf notes                                                            */
e2ce63b
 
e2ce63b
-int elf_xen_parse_note(struct elf_binary *elf,
e2ce63b
+elf_errorstatus elf_xen_parse_note(struct elf_binary *elf,
e2ce63b
                        struct elf_dom_parms *parms,
e2ce63b
                        ELF_HANDLE_DECL(elf_note) note)
e2ce63b
 {
e2ce63b
@@ -121,7 +121,7 @@ int elf_xen_parse_note(struct elf_binary *elf,
e2ce63b
 
e2ce63b
     const char *str = NULL;
e2ce63b
     uint64_t val = 0;
e2ce63b
-    int type = elf_uval(elf, note, type);
e2ce63b
+    unsigned type = elf_uval(elf, note, type);
e2ce63b
 
e2ce63b
     if ( (type >= sizeof(note_desc) / sizeof(note_desc[0])) ||
e2ce63b
          (note_desc[type].name == NULL) )
1c5bb4e
@@ -206,12 +206,14 @@ int elf_xen_parse_note(struct elf_binary *elf,
e2ce63b
     return 0;
e2ce63b
 }
e2ce63b
 
e2ce63b
-static int elf_xen_parse_notes(struct elf_binary *elf,
1c5bb4e
+#define ELF_NOTE_INVALID (~0U)
1c5bb4e
+
e2ce63b
+static unsigned elf_xen_parse_notes(struct elf_binary *elf,
e2ce63b
                                struct elf_dom_parms *parms,
e2ce63b
                                ELF_PTRVAL_CONST_VOID start,
e2ce63b
                                ELF_PTRVAL_CONST_VOID end)
e2ce63b
 {
e2ce63b
-    int xen_elfnotes = 0;
e2ce63b
+    unsigned xen_elfnotes = 0;
e2ce63b
     ELF_HANDLE_DECL(elf_note) note;
e2ce63b
     const char *note_name;
e2ce63b
 
1c5bb4e
@@ -227,7 +229,7 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
e2ce63b
         if ( strcmp(note_name, "Xen") )
e2ce63b
             continue;
e2ce63b
         if ( elf_xen_parse_note(elf, parms, note) )
e2ce63b
-            return -1;
1c5bb4e
+            return ELF_NOTE_INVALID;
e2ce63b
         xen_elfnotes++;
e2ce63b
     }
e2ce63b
     return xen_elfnotes;
1c5bb4e
@@ -236,12 +238,12 @@ static int elf_xen_parse_notes(struct elf_binary *elf,
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 /* __xen_guest section                                                      */
e2ce63b
 
e2ce63b
-int elf_xen_parse_guest_info(struct elf_binary *elf,
e2ce63b
+elf_errorstatus elf_xen_parse_guest_info(struct elf_binary *elf,
e2ce63b
                              struct elf_dom_parms *parms)
e2ce63b
 {
e2ce63b
     ELF_PTRVAL_CONST_CHAR h;
e2ce63b
-    char name[32], value[128];
e2ce63b
-    int len;
e2ce63b
+    unsigned char name[32], value[128];
e2ce63b
+    unsigned len;
e2ce63b
 
e2ce63b
     h = parms->guest_info;
e2ce63b
 #define STAR(h) (elf_access_unsigned(elf, (h), 0, 1))
1c5bb4e
@@ -324,13 +326,13 @@ int elf_xen_parse_guest_info(struct elf_binary *elf,
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 /* sanity checks                                                            */
e2ce63b
 
e2ce63b
-static int elf_xen_note_check(struct elf_binary *elf,
e2ce63b
+static elf_errorstatus elf_xen_note_check(struct elf_binary *elf,
e2ce63b
                               struct elf_dom_parms *parms)
e2ce63b
 {
e2ce63b
     if ( (ELF_PTRVAL_INVALID(parms->elf_note_start)) &&
e2ce63b
          (ELF_PTRVAL_INVALID(parms->guest_info)) )
e2ce63b
     {
e2ce63b
-        int machine = elf_uval(elf, elf->ehdr, e_machine);
e2ce63b
+        unsigned machine = elf_uval(elf, elf->ehdr, e_machine);
e2ce63b
         if ( (machine == EM_386) || (machine == EM_X86_64) )
e2ce63b
         {
e2ce63b
             elf_err(elf, "%s: ERROR: Not a Xen-ELF image: "
1c5bb4e
@@ -362,7 +364,7 @@ static int elf_xen_note_check(struct elf_binary *elf,
e2ce63b
     return 0;
e2ce63b
 }
e2ce63b
 
e2ce63b
-static int elf_xen_addr_calc_check(struct elf_binary *elf,
e2ce63b
+static elf_errorstatus elf_xen_addr_calc_check(struct elf_binary *elf,
e2ce63b
                                    struct elf_dom_parms *parms)
e2ce63b
 {
e2ce63b
     if ( (parms->elf_paddr_offset != UNSET_ADDR) &&
1c5bb4e
@@ -448,13 +450,13 @@ static int elf_xen_addr_calc_check(struct elf_binary *elf,
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 /* glue it all together ...                                                 */
e2ce63b
 
e2ce63b
-int elf_xen_parse(struct elf_binary *elf,
e2ce63b
+elf_errorstatus elf_xen_parse(struct elf_binary *elf,
e2ce63b
                   struct elf_dom_parms *parms)
e2ce63b
 {
e2ce63b
     ELF_HANDLE_DECL(elf_shdr) shdr;
e2ce63b
     ELF_HANDLE_DECL(elf_phdr) phdr;
e2ce63b
-    int xen_elfnotes = 0;
e2ce63b
-    int i, count, rc;
e2ce63b
+    unsigned xen_elfnotes = 0;
e2ce63b
+    unsigned i, count, more_notes;
e2ce63b
 
e2ce63b
     elf_memset_unchecked(parms, 0, sizeof(*parms));
e2ce63b
     parms->virt_base = UNSET_ADDR;
1c5bb4e
@@ -479,13 +481,13 @@ int elf_xen_parse(struct elf_binary *elf,
e2ce63b
         if (elf_uval(elf, phdr, p_offset) == 0)
e2ce63b
              continue;
e2ce63b
 
e2ce63b
-        rc = elf_xen_parse_notes(elf, parms,
e2ce63b
+        more_notes = elf_xen_parse_notes(elf, parms,
e2ce63b
                                  elf_segment_start(elf, phdr),
e2ce63b
                                  elf_segment_end(elf, phdr));
e2ce63b
-        if ( rc == -1 )
1c5bb4e
+        if ( more_notes == ELF_NOTE_INVALID )
e2ce63b
             return -1;
e2ce63b
 
e2ce63b
-        xen_elfnotes += rc;
e2ce63b
+        xen_elfnotes += more_notes;
e2ce63b
     }
e2ce63b
 
e2ce63b
     /*
1c5bb4e
@@ -502,17 +504,17 @@ int elf_xen_parse(struct elf_binary *elf,
e2ce63b
             if ( elf_uval(elf, shdr, sh_type) != SHT_NOTE )
e2ce63b
                 continue;
e2ce63b
 
e2ce63b
-            rc = elf_xen_parse_notes(elf, parms,
e2ce63b
+            more_notes = elf_xen_parse_notes(elf, parms,
e2ce63b
                                      elf_section_start(elf, shdr),
e2ce63b
                                      elf_section_end(elf, shdr));
e2ce63b
 
e2ce63b
-            if ( rc == -1 )
1c5bb4e
+            if ( more_notes == ELF_NOTE_INVALID )
e2ce63b
                 return -1;
e2ce63b
 
e2ce63b
-            if ( xen_elfnotes == 0 && rc > 0 )
e2ce63b
+            if ( xen_elfnotes == 0 && more_notes > 0 )
e2ce63b
                 elf_msg(elf, "%s: using notes from SHT_NOTE section\n", __FUNCTION__);
e2ce63b
 
e2ce63b
-            xen_elfnotes += rc;
e2ce63b
+            xen_elfnotes += more_notes;
e2ce63b
         }
e2ce63b
 
e2ce63b
     }
e2ce63b
diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
e2ce63b
index 5895a6b..459c973 100644
e2ce63b
--- a/xen/common/libelf/libelf-loader.c
e2ce63b
+++ b/xen/common/libelf/libelf-loader.c
e2ce63b
@@ -20,7 +20,7 @@
e2ce63b
 
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 
e2ce63b
-int elf_init(struct elf_binary *elf, const char *image_input, size_t size)
e2ce63b
+elf_errorstatus elf_init(struct elf_binary *elf, const char *image_input, size_t size)
e2ce63b
 {
e2ce63b
     ELF_HANDLE_DECL(elf_shdr) shdr;
e2ce63b
     uint64_t i, count, section, offset;
e2ce63b
@@ -121,7 +121,7 @@ void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
e2ce63b
 {
e2ce63b
     uint64_t sz;
e2ce63b
     ELF_HANDLE_DECL(elf_shdr) shdr;
e2ce63b
-    int i, type;
e2ce63b
+    unsigned i, type;
e2ce63b
 
e2ce63b
     if ( !ELF_HANDLE_VALID(elf->sym_tab) )
e2ce63b
         return;
e2ce63b
@@ -157,7 +157,7 @@ static void elf_load_bsdsyms(struct elf_binary *elf)
e2ce63b
     ELF_PTRVAL_VOID symbase;
e2ce63b
     ELF_PTRVAL_VOID symtab_addr;
e2ce63b
     ELF_HANDLE_DECL_NONCONST(elf_shdr) shdr;
e2ce63b
-    int i, type;
e2ce63b
+    unsigned i, type;
e2ce63b
 
e2ce63b
     if ( !elf->bsd_symtab_pstart )
e2ce63b
         return;
e2ce63b
@@ -190,7 +190,7 @@ do {                                            \
e2ce63b
     elf_memcpy_safe(elf, ELF_HANDLE_PTRVAL(shdr),
e2ce63b
                     ELF_IMAGE_BASE(elf) + elf_uval(elf, elf->ehdr, e_shoff),
e2ce63b
                     sz);
e2ce63b
-    maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (long)maxva + sz);
e2ce63b
+    maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (unsigned long)maxva + sz);
e2ce63b
 
e2ce63b
     for ( i = 0; i < elf_shdr_count(elf); i++ )
e2ce63b
     {
e2ce63b
@@ -203,10 +203,10 @@ do {                                            \
e2ce63b
              elf_memcpy_safe(elf, maxva, elf_section_start(elf, shdr), sz);
e2ce63b
              /* Mangled to be based on ELF header location. */
e2ce63b
              elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
e2ce63b
-             maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (long)maxva + sz);
e2ce63b
+             maxva = ELF_OBSOLETE_VOIDP_CAST elf_round_up(elf, (unsigned long)maxva + sz);
e2ce63b
         }
e2ce63b
         shdr = ELF_MAKE_HANDLE(elf_shdr, ELF_HANDLE_PTRVAL(shdr) +
e2ce63b
-                            (long)elf_uval(elf, elf->ehdr, e_shentsize));
e2ce63b
+                            (unsigned long)elf_uval(elf, elf->ehdr, e_shentsize));
e2ce63b
     }
e2ce63b
 
e2ce63b
     /* Write down the actual sym size. */
e2ce63b
diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
1c5bb4e
index 78b2f99..4fb2d38 100644
e2ce63b
--- a/xen/common/libelf/libelf-tools.c
e2ce63b
+++ b/xen/common/libelf/libelf-tools.c
1c5bb4e
@@ -122,19 +122,19 @@ uint64_t elf_access_unsigned(struct elf_binary * elf, elf_ptrval base,
e2ce63b
 
e2ce63b
 uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr)
e2ce63b
 {
e2ce63b
-    int elf_round = (elf_64bit(elf) ? 8 : 4) - 1;
1c5bb4e
+    uint64_t elf_round = (elf_64bit(elf) ? 8 : 4) - 1;
e2ce63b
 
e2ce63b
     return (addr + elf_round) & ~elf_round;
e2ce63b
 }
e2ce63b
 
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 
e2ce63b
-int elf_shdr_count(struct elf_binary *elf)
e2ce63b
+unsigned elf_shdr_count(struct elf_binary *elf)
e2ce63b
 {
e2ce63b
     return elf_uval(elf, elf->ehdr, e_shnum);
e2ce63b
 }
e2ce63b
 
e2ce63b
-int elf_phdr_count(struct elf_binary *elf)
e2ce63b
+unsigned elf_phdr_count(struct elf_binary *elf)
e2ce63b
 {
e2ce63b
     return elf_uval(elf, elf->ehdr, e_phnum);
e2ce63b
 }
1c5bb4e
@@ -144,7 +144,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
e2ce63b
     uint64_t count = elf_shdr_count(elf);
e2ce63b
     ELF_HANDLE_DECL(elf_shdr) shdr;
e2ce63b
     const char *sname;
e2ce63b
-    int i;
e2ce63b
+    unsigned i;
e2ce63b
 
e2ce63b
     for ( i = 0; i < count; i++ )
e2ce63b
     {
1c5bb4e
@@ -156,7 +156,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n
e2ce63b
     return ELF_INVALID_HANDLE(elf_shdr);
e2ce63b
 }
e2ce63b
 
e2ce63b
-ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index)
e2ce63b
+ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, unsigned index)
e2ce63b
 {
e2ce63b
     uint64_t count = elf_shdr_count(elf);
e2ce63b
     ELF_PTRVAL_CONST_VOID ptr;
1c5bb4e
@@ -170,7 +170,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index)
e2ce63b
     return ELF_MAKE_HANDLE(elf_shdr, ptr);
e2ce63b
 }
e2ce63b
 
e2ce63b
-ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int index)
e2ce63b
+ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, unsigned index)
e2ce63b
 {
e2ce63b
     uint64_t count = elf_uval(elf, elf->ehdr, e_phnum);
e2ce63b
     ELF_PTRVAL_CONST_VOID ptr;
1c5bb4e
@@ -264,7 +264,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym
e2ce63b
     return ELF_INVALID_HANDLE(elf_sym);
e2ce63b
 }
e2ce63b
 
e2ce63b
-ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index)
e2ce63b
+ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, unsigned index)
e2ce63b
 {
e2ce63b
     ELF_PTRVAL_CONST_VOID ptr = elf_section_start(elf, elf->sym_tab);
e2ce63b
     ELF_HANDLE_DECL(elf_sym) sym;
1c5bb4e
@@ -280,7 +280,7 @@ const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note
e2ce63b
 
e2ce63b
 ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
e2ce63b
 {
e2ce63b
-    int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
e2ce63b
+    unsigned namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
e2ce63b
 
e2ce63b
     return ELF_HANDLE_PTRVAL(note) + elf_size(elf, note) + namesz;
e2ce63b
 }
1c5bb4e
@@ -288,7 +288,7 @@ ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_
e2ce63b
 uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
e2ce63b
 {
e2ce63b
     ELF_PTRVAL_CONST_VOID desc = elf_note_desc(elf, note);
e2ce63b
-    int descsz = elf_uval(elf, note, descsz);
e2ce63b
+    unsigned descsz = elf_uval(elf, note, descsz);
e2ce63b
 
e2ce63b
     switch (descsz)
e2ce63b
     {
1c5bb4e
@@ -303,8 +303,8 @@ uint64_t elf_note_numeric(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note
e2ce63b
 }
e2ce63b
 ELF_HANDLE_DECL(elf_note) elf_note_next(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note)
e2ce63b
 {
e2ce63b
-    int namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
e2ce63b
-    int descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
e2ce63b
+    unsigned namesz = (elf_uval(elf, note, namesz) + 3) & ~3;
e2ce63b
+    unsigned descsz = (elf_uval(elf, note, descsz) + 3) & ~3;
e2ce63b
 
e2ce63b
     return ELF_MAKE_HANDLE(elf_note, ELF_HANDLE_PTRVAL(note) + elf_size(elf, note) + namesz + descsz);
e2ce63b
 }
e2ce63b
diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
1c5bb4e
index 152a33d..9e709c2 100644
e2ce63b
--- a/xen/include/xen/libelf.h
e2ce63b
+++ b/xen/include/xen/libelf.h
e2ce63b
@@ -31,6 +31,9 @@
e2ce63b
 
e2ce63b
 #include <stdbool.h>
e2ce63b
 
e2ce63b
+typedef int elf_errorstatus; /* 0: ok; -ve (normally -1): error */
e2ce63b
+typedef int elf_negerrnoval; /* 0: ok; -EFOO: error */
e2ce63b
+
e2ce63b
 #undef ELFSIZE
e2ce63b
 #include "elfstructs.h"
e2ce63b
 #ifdef __XEN__
1c5bb4e
@@ -330,12 +333,12 @@ bool elf_access_ok(struct elf_binary * elf,
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 /* xc_libelf_tools.c                                                        */
e2ce63b
 
e2ce63b
-int elf_shdr_count(struct elf_binary *elf);
e2ce63b
-int elf_phdr_count(struct elf_binary *elf);
e2ce63b
+unsigned elf_shdr_count(struct elf_binary *elf);
e2ce63b
+unsigned elf_phdr_count(struct elf_binary *elf);
e2ce63b
 
e2ce63b
 ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *name);
e2ce63b
-ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, int index);
e2ce63b
-ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, int index);
e2ce63b
+ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_index(struct elf_binary *elf, unsigned index);
e2ce63b
+ELF_HANDLE_DECL(elf_phdr) elf_phdr_by_index(struct elf_binary *elf, unsigned index);
e2ce63b
 
e2ce63b
 const char *elf_section_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr); /* might return NULL if inputs are invalid */
e2ce63b
 ELF_PTRVAL_CONST_VOID elf_section_start(struct elf_binary *elf, ELF_HANDLE_DECL(elf_shdr) shdr);
1c5bb4e
@@ -345,7 +348,7 @@ ELF_PTRVAL_CONST_VOID elf_segment_start(struct elf_binary *elf, ELF_HANDLE_DECL(
e2ce63b
 ELF_PTRVAL_CONST_VOID elf_segment_end(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr);
e2ce63b
 
e2ce63b
 ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *symbol);
e2ce63b
-ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, int index);
e2ce63b
+ELF_HANDLE_DECL(elf_sym) elf_sym_by_index(struct elf_binary *elf, unsigned index);
e2ce63b
 
e2ce63b
 const char *elf_note_name(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note); /* may return NULL */
e2ce63b
 ELF_PTRVAL_CONST_VOID elf_note_desc(struct elf_binary *elf, ELF_HANDLE_DECL(elf_note) note);
1c5bb4e
@@ -360,7 +363,7 @@ bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 /* xc_libelf_loader.c                                                       */
e2ce63b
 
e2ce63b
-int elf_init(struct elf_binary *elf, const char *image, size_t size);
e2ce63b
+elf_errorstatus elf_init(struct elf_binary *elf, const char *image, size_t size);
e2ce63b
   /*
e2ce63b
    * image and size must be correct.  They will be recorded in
e2ce63b
    * *elf, and must remain valid while the elf is in use.
1c5bb4e
@@ -386,7 +389,7 @@ const char *elf_check_broken(const struct elf_binary *elf); /* NULL means OK */
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 /* xc_libelf_relocate.c                                                     */
e2ce63b
 
e2ce63b
-int elf_reloc(struct elf_binary *elf);
e2ce63b
+elf_errorstatus elf_reloc(struct elf_binary *elf);
e2ce63b
 
e2ce63b
 /* ------------------------------------------------------------------------ */
e2ce63b
 /* xc_libelf_dominfo.c                                                      */
1c5bb4e
@@ -420,7 +423,7 @@ struct elf_dom_parms {
e2ce63b
     char guest_ver[16];
e2ce63b
     char xen_ver[16];
e2ce63b
     char loader[16];
e2ce63b
-    int pae;
e2ce63b
+    int pae; /* some kind of enum apparently */
e2ce63b
     bool bsd_symtab;
e2ce63b
     uint64_t virt_base;
e2ce63b
     uint64_t virt_entry;
e2ce63b
-- 
e2ce63b
1.7.2.5
e2ce63b