qemu-trivial
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] hw/elf_ops.h: switch to ssize_t for elf loader return type


From: Luc Michel
Subject: Re: [PATCH] hw/elf_ops.h: switch to ssize_t for elf loader return type
Date: Tue, 12 Oct 2021 17:08:23 +0200
User-agent: NeoMutt/20171215

On 21:28 Wed 06 Oct     , Luc Michel wrote:
> Until now, int was used as the return type for all the ELF
> loader related functions. The returned value is the sum of all loaded
> program headers "MemSize" fields.
> 
> Because of the overflow check in elf_ops.h, trying to load an ELF bigger
> than INT_MAX will fail. Switch to ssize_t to remove this limitation.
> 
> Signed-off-by: Luc Michel <lmichel@kalray.eu>

Ping?
Cc'ing qemu-trivial. I guess it's simple enough.

Thanks.

-- 
Luc

> ---
>  include/hw/elf_ops.h | 25 +++++++++---------
>  include/hw/loader.h  | 60 ++++++++++++++++++++++----------------------
>  hw/core/loader.c     | 60 +++++++++++++++++++++++---------------------
>  3 files changed, 74 insertions(+), 71 deletions(-)
> 
> diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
> index 1c37cec4ae..5c2ea0339e 100644
> --- a/include/hw/elf_ops.h
> +++ b/include/hw/elf_ops.h
> @@ -310,24 +310,25 @@ static struct elf_note *glue(get_elf_note_type, 
> SZ)(struct elf_note *nhdr,
>      }
>  
>      return nhdr;
>  }
>  
> -static int glue(load_elf, SZ)(const char *name, int fd,
> -                              uint64_t (*elf_note_fn)(void *, void *, bool),
> -                              uint64_t (*translate_fn)(void *, uint64_t),
> -                              void *translate_opaque,
> -                              int must_swab, uint64_t *pentry,
> -                              uint64_t *lowaddr, uint64_t *highaddr,
> -                              uint32_t *pflags, int elf_machine,
> -                              int clear_lsb, int data_swab,
> -                              AddressSpace *as, bool load_rom,
> -                              symbol_fn_t sym_cb)
> +static ssize_t glue(load_elf, SZ)(const char *name, int fd,
> +                                  uint64_t (*elf_note_fn)(void *, void *, 
> bool),
> +                                  uint64_t (*translate_fn)(void *, uint64_t),
> +                                  void *translate_opaque,
> +                                  int must_swab, uint64_t *pentry,
> +                                  uint64_t *lowaddr, uint64_t *highaddr,
> +                                  uint32_t *pflags, int elf_machine,
> +                                  int clear_lsb, int data_swab,
> +                                  AddressSpace *as, bool load_rom,
> +                                  symbol_fn_t sym_cb)
>  {
>      struct elfhdr ehdr;
>      struct elf_phdr *phdr = NULL, *ph;
> -    int size, i, total_size;
> +    int size, i;
> +    ssize_t total_size;
>      elf_word mem_size, file_size, data_offset;
>      uint64_t addr, low = (uint64_t)-1, high = 0;
>      GMappedFile *mapped_file = NULL;
>      uint8_t *data = NULL;
>      int ret = ELF_LOAD_FAILED;
> @@ -480,11 +481,11 @@ static int glue(load_elf, SZ)(const char *name, int fd,
>                          }
>                      }
>                  }
>              }
>  
> -            if (mem_size > INT_MAX - total_size) {
> +            if (mem_size > SSIZE_MAX - total_size) {
>                  ret = ELF_LOAD_TOO_BIG;
>                  goto fail;
>              }
>  
>              /* address_offset is hack for kernel images that are
> diff --git a/include/hw/loader.h b/include/hw/loader.h
> index 81104cb02f..4fa485bd61 100644
> --- a/include/hw/loader.h
> +++ b/include/hw/loader.h
> @@ -88,11 +88,11 @@ int load_image_gzipped(const char *filename, hwaddr addr, 
> uint64_t max_sz);
>  #define ELF_LOAD_FAILED       -1
>  #define ELF_LOAD_NOT_ELF      -2
>  #define ELF_LOAD_WRONG_ARCH   -3
>  #define ELF_LOAD_WRONG_ENDIAN -4
>  #define ELF_LOAD_TOO_BIG      -5
> -const char *load_elf_strerror(int error);
> +const char *load_elf_strerror(ssize_t error);
>  
>  /** load_elf_ram_sym:
>   * @filename: Path of ELF file
>   * @elf_note_fn: optional function to parse ELF Note type
>   *               passed via @translate_opaque
> @@ -126,52 +126,52 @@ const char *load_elf_strerror(int error);
>   * ELF header and no checks will be carried out against the machine type.
>   */
>  typedef void (*symbol_fn_t)(const char *st_name, int st_info,
>                              uint64_t st_value, uint64_t st_size);
>  
> -int load_elf_ram_sym(const char *filename,
> +ssize_t load_elf_ram_sym(const char *filename,
> +                         uint64_t (*elf_note_fn)(void *, void *, bool),
> +                         uint64_t (*translate_fn)(void *, uint64_t),
> +                         void *translate_opaque, uint64_t *pentry,
> +                         uint64_t *lowaddr, uint64_t *highaddr,
> +                         uint32_t *pflags, int big_endian, int elf_machine,
> +                         int clear_lsb, int data_swab,
> +                         AddressSpace *as, bool load_rom, symbol_fn_t 
> sym_cb);
> +
> +/** load_elf_ram:
> + * Same as load_elf_ram_sym(), but doesn't allow the caller to specify a
> + * symbol callback function
> + */
> +ssize_t load_elf_ram(const char *filename,
>                       uint64_t (*elf_note_fn)(void *, void *, bool),
>                       uint64_t (*translate_fn)(void *, uint64_t),
>                       void *translate_opaque, uint64_t *pentry,
>                       uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pflags,
> -                     int big_endian, int elf_machine,
> -                     int clear_lsb, int data_swab,
> -                     AddressSpace *as, bool load_rom, symbol_fn_t sym_cb);
> -
> -/** load_elf_ram:
> - * Same as load_elf_ram_sym(), but doesn't allow the caller to specify a
> - * symbol callback function
> - */
> -int load_elf_ram(const char *filename,
> -                 uint64_t (*elf_note_fn)(void *, void *, bool),
> -                 uint64_t (*translate_fn)(void *, uint64_t),
> -                 void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
> -                 uint64_t *highaddr, uint32_t *pflags, int big_endian,
> -                 int elf_machine, int clear_lsb, int data_swab,
> -                 AddressSpace *as, bool load_rom);
> +                     int big_endian, int elf_machine, int clear_lsb,
> +                     int data_swab, AddressSpace *as, bool load_rom);
>  
>  /** load_elf_as:
>   * Same as load_elf_ram(), but always loads the elf as ROM
>   */
> -int load_elf_as(const char *filename,
> -                uint64_t (*elf_note_fn)(void *, void *, bool),
> -                uint64_t (*translate_fn)(void *, uint64_t),
> -                void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
> -                uint64_t *highaddr, uint32_t *pflags, int big_endian,
> -                int elf_machine, int clear_lsb, int data_swab,
> -                AddressSpace *as);
> +ssize_t load_elf_as(const char *filename,
> +                    uint64_t (*elf_note_fn)(void *, void *, bool),
> +                    uint64_t (*translate_fn)(void *, uint64_t),
> +                    void *translate_opaque, uint64_t *pentry, uint64_t 
> *lowaddr,
> +                    uint64_t *highaddr, uint32_t *pflags, int big_endian,
> +                    int elf_machine, int clear_lsb, int data_swab,
> +                    AddressSpace *as);
>  
>  /** load_elf:
>   * Same as load_elf_as(), but doesn't allow the caller to specify an
>   * AddressSpace.
>   */
> -int load_elf(const char *filename,
> -             uint64_t (*elf_note_fn)(void *, void *, bool),
> -             uint64_t (*translate_fn)(void *, uint64_t),
> -             void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
> -             uint64_t *highaddr, uint32_t *pflags, int big_endian,
> -             int elf_machine, int clear_lsb, int data_swab);
> +ssize_t load_elf(const char *filename,
> +                 uint64_t (*elf_note_fn)(void *, void *, bool),
> +                 uint64_t (*translate_fn)(void *, uint64_t),
> +                 void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
> +                 uint64_t *highaddr, uint32_t *pflags, int big_endian,
> +                 int elf_machine, int clear_lsb, int data_swab);
>  
>  /** load_elf_hdr:
>   * @filename: Path of ELF file
>   * @hdr: Buffer to populate with header data. Header data will not be
>   * filled if set to NULL.
> diff --git a/hw/core/loader.c b/hw/core/loader.c
> index c623318b73..c7f97fdce8 100644
> --- a/hw/core/loader.c
> +++ b/hw/core/loader.c
> @@ -324,11 +324,11 @@ static void *load_at(int fd, off_t offset, size_t size)
>  #define elf_sword        int64_t
>  #define bswapSZs     bswap64s
>  #define SZ           64
>  #include "hw/elf_ops.h"
>  
> -const char *load_elf_strerror(int error)
> +const char *load_elf_strerror(ssize_t error)
>  {
>      switch (error) {
>      case 0:
>          return "No error";
>      case ELF_LOAD_FAILED:
> @@ -400,62 +400,64 @@ void load_elf_hdr(const char *filename, void *hdr, bool 
> *is64, Error **errp)
>  fail:
>      close(fd);
>  }
>  
>  /* return < 0 if error, otherwise the number of bytes loaded in memory */
> -int load_elf(const char *filename,
> -             uint64_t (*elf_note_fn)(void *, void *, bool),
> -             uint64_t (*translate_fn)(void *, uint64_t),
> -             void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
> -             uint64_t *highaddr, uint32_t *pflags, int big_endian,
> -             int elf_machine, int clear_lsb, int data_swab)
> +ssize_t load_elf(const char *filename,
> +                 uint64_t (*elf_note_fn)(void *, void *, bool),
> +                 uint64_t (*translate_fn)(void *, uint64_t),
> +                 void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
> +                 uint64_t *highaddr, uint32_t *pflags, int big_endian,
> +                 int elf_machine, int clear_lsb, int data_swab)
>  {
>      return load_elf_as(filename, elf_note_fn, translate_fn, translate_opaque,
>                         pentry, lowaddr, highaddr, pflags, big_endian,
>                         elf_machine, clear_lsb, data_swab, NULL);
>  }
>  
>  /* return < 0 if error, otherwise the number of bytes loaded in memory */
> -int load_elf_as(const char *filename,
> -                uint64_t (*elf_note_fn)(void *, void *, bool),
> -                uint64_t (*translate_fn)(void *, uint64_t),
> -                void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
> -                uint64_t *highaddr, uint32_t *pflags, int big_endian,
> -                int elf_machine, int clear_lsb, int data_swab, AddressSpace 
> *as)
> +ssize_t load_elf_as(const char *filename,
> +                    uint64_t (*elf_note_fn)(void *, void *, bool),
> +                    uint64_t (*translate_fn)(void *, uint64_t),
> +                    void *translate_opaque, uint64_t *pentry, uint64_t 
> *lowaddr,
> +                    uint64_t *highaddr, uint32_t *pflags, int big_endian,
> +                    int elf_machine, int clear_lsb, int data_swab,
> +                    AddressSpace *as)
>  {
>      return load_elf_ram(filename, elf_note_fn, translate_fn, 
> translate_opaque,
>                          pentry, lowaddr, highaddr, pflags, big_endian,
>                          elf_machine, clear_lsb, data_swab, as, true);
>  }
>  
>  /* return < 0 if error, otherwise the number of bytes loaded in memory */
> -int load_elf_ram(const char *filename,
> -                 uint64_t (*elf_note_fn)(void *, void *, bool),
> -                 uint64_t (*translate_fn)(void *, uint64_t),
> -                 void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
> -                 uint64_t *highaddr, uint32_t *pflags, int big_endian,
> -                 int elf_machine, int clear_lsb, int data_swab,
> -                 AddressSpace *as, bool load_rom)
> +ssize_t load_elf_ram(const char *filename,
> +                     uint64_t (*elf_note_fn)(void *, void *, bool),
> +                     uint64_t (*translate_fn)(void *, uint64_t),
> +                     void *translate_opaque, uint64_t *pentry,
> +                     uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pflags,
> +                     int big_endian, int elf_machine, int clear_lsb,
> +                     int data_swab, AddressSpace *as, bool load_rom)
>  {
>      return load_elf_ram_sym(filename, elf_note_fn,
>                              translate_fn, translate_opaque,
>                              pentry, lowaddr, highaddr, pflags, big_endian,
>                              elf_machine, clear_lsb, data_swab, as,
>                              load_rom, NULL);
>  }
>  
>  /* return < 0 if error, otherwise the number of bytes loaded in memory */
> -int load_elf_ram_sym(const char *filename,
> -                     uint64_t (*elf_note_fn)(void *, void *, bool),
> -                     uint64_t (*translate_fn)(void *, uint64_t),
> -                     void *translate_opaque, uint64_t *pentry,
> -                     uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pflags,
> -                     int big_endian, int elf_machine,
> -                     int clear_lsb, int data_swab,
> -                     AddressSpace *as, bool load_rom, symbol_fn_t sym_cb)
> +ssize_t load_elf_ram_sym(const char *filename,
> +                         uint64_t (*elf_note_fn)(void *, void *, bool),
> +                         uint64_t (*translate_fn)(void *, uint64_t),
> +                         void *translate_opaque, uint64_t *pentry,
> +                         uint64_t *lowaddr, uint64_t *highaddr,
> +                         uint32_t *pflags, int big_endian, int elf_machine,
> +                         int clear_lsb, int data_swab,
> +                         AddressSpace *as, bool load_rom, symbol_fn_t sym_cb)
>  {
> -    int fd, data_order, target_data_order, must_swab, ret = ELF_LOAD_FAILED;
> +    int fd, data_order, target_data_order, must_swab;
> +    ssize_t ret = ELF_LOAD_FAILED;
>      uint8_t e_ident[EI_NIDENT];
>  
>      fd = open(filename, O_RDONLY | O_BINARY);
>      if (fd < 0) {
>          perror(filename);
> -- 
> 2.17.1
> 

-- 







reply via email to

[Prev in Thread] Current Thread [Next in Thread]