Message ID | 20200401145755.891080-2-stefanb@linux.vnet.ibm.com |
---|---|
State | Superseded |
Headers | show |
Series | vTPM: Measure the bootloader | expand |
On 02/04/2020 01:57, Stefan Berger wrote: > From: Stefan Berger <stefanb@linux.ibm.com> > > Implement elf_get_file_size to determine the size of an ELF image > that has been loaded into a buffer much larger than the actual size > of the original file. We determine the size by searching for the > farthest offset declared by the ELF headers. > > Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> > --- > include/helpers.h | 2 ++ > include/libelf.h | 14 ++++++++++ > lib/libelf/elf.c | 26 ++++++++++++++++++ > lib/libelf/elf32.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ > lib/libelf/elf64.c | 56 ++++++++++++++++++++++++++++++++++++++ > 5 files changed, 166 insertions(+) > > diff --git a/include/helpers.h b/include/helpers.h > index 47b2674..112184f 100644 > --- a/include/helpers.h > +++ b/include/helpers.h > @@ -51,5 +51,7 @@ extern unsigned long SLOF_get_vtpm_unit(void); > const typeof(((type *)0)->member)* struct_ptr = (ptr); \ > (type *)((char *)struct_ptr - offset_of(type, member)); }) > #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) > +#define ROUNDUP(x,v) ((((x) + ((v) - 1)) / (v)) * (v)) > +#define MAX(x,y) ((x) > (y) ? (x) : (y)) > > #endif > diff --git a/include/libelf.h b/include/libelf.h > index 5fbf279..48ff4d7 100644 > --- a/include/libelf.h > +++ b/include/libelf.h > @@ -96,4 +96,18 @@ void elf_relocate64(void *file_addr, signed long offset); > > int elf_forth_claim(void *addr, long size); > > +long elf_get_file_size(const void *buffer, const long buffer_size); > +long elf_get_file_size32(const void *buffer, const long buffer_size); > +long elf_get_file_size64(const void *buffer, const long buffer_size); > + > +#ifdef __BIG_ENDIAN__ > +#define elf64_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2MSB ? (x) : bswap_64(x)) > +#define elf32_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2MSB ? (x) : bswap_32(x)) > +#define elf16_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2MSB ? (x) : bswap_16(x)) > +#else > +#define elf64_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2LSB ? (x) : bswap_64(x)) > +#define elf32_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2LSB ? (x) : bswap_32(x)) > +#define elf16_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2LSB ? (x) : bswap_16(x)) > +#endif > + > #endif /* __LIBELF_H */ > diff --git a/lib/libelf/elf.c b/lib/libelf/elf.c > index 5204bc3..d368454 100644 > --- a/lib/libelf/elf.c > +++ b/lib/libelf/elf.c > @@ -196,3 +196,29 @@ elf_get_base_addr(void *file_addr) > > return -1; > } > + > +/** > + * Get the file size of the ELF image that has been loaded into a > + * buffer larger than the size of the file > + * @return The size of the ELF image or < 0 for error > + */ > +long elf_get_file_size(const void *buffer, const long buffer_size) > +{ > + const struct ehdr *ehdr = (const struct ehdr *)buffer; > + > + if (buffer_size < sizeof(struct ehdr)) > + return -1; > + > + /* check if it is an ELF image at all */ > + if (cpu_to_be32(ehdr->ei_ident) != 0x7f454c46) > + return -1; > + > + switch (ehdr->ei_class) { > + case 1: > + return elf_get_file_size32(buffer, buffer_size); > + case 2: > + return elf_get_file_size64(buffer, buffer_size); > + } > + > + return -1; > +} > diff --git a/lib/libelf/elf32.c b/lib/libelf/elf32.c > index fea5cf4..7ea85f0 100644 > --- a/lib/libelf/elf32.c > +++ b/lib/libelf/elf32.c > @@ -17,6 +17,7 @@ > #include <string.h> > #include <libelf.h> > #include <byteorder.h> > +#include <helpers.h> > > struct ehdr32 { > uint32_t ei_ident; > @@ -50,6 +51,18 @@ struct phdr32 { > uint32_t p_align; > }; > > +struct shdr32 { > + uint32_t sh_name; > + uint32_t sh_type; > + uint32_t sh_flags; > + uint32_t sh_addr; > + uint32_t sh_offset; > + uint32_t sh_size; > + uint32_t sh_link; > + uint32_t sh_info; > + uint32_t sh_addralign; > + uint32_t sh_entsize; > +}; > > static struct phdr32* > get_phdr32(void *file_addr) > @@ -191,3 +204,58 @@ elf_byteswap_header32(void *file_addr) > phdr = (struct phdr32 *)(((uint8_t *)phdr) + ehdr->e_phentsize); > } > } > + > +/* > + * Determine the size of an ELF image that has been loaded into > + * a buffer larger than its size. We search all program headers > + * and sections for the one that shows the farthest extent of the > + * file. > + * @return Return -1 on error, size of file otherwise. > + */ > +long elf_get_file_size32(const void *buffer, const long buffer_size) > +{ > + const struct ehdr32 *ehdr = (const struct ehdr32 *) buffer; > + const uint8_t *buffer_end = buffer + buffer_size; > + const struct phdr32 *phdr; > + const struct shdr32 *shdr; > + long elf_size = -1; > + uint16_t entsize; > + unsigned i; > + > + if (buffer_size < sizeof(struct ehdr) || ehdr->e_ehsize != 52) What is 52? sizeof(struct ehdr32)? Why "!=" rather ">=" ? > + return -1; > + > + phdr = buffer + elf32_to_cpu(ehdr->e_phoff, ehdr); > + entsize = elf16_to_cpu(ehdr->e_phentsize, ehdr); > + for (i = 0; i < elf16_to_cpu(ehdr->e_phnum, ehdr); i++) { > + if (((uint8_t *)phdr) + entsize > buffer_end) > + return -1; > + > + elf_size = MAX(elf32_to_cpu(phdr->p_offset, ehdr) + > + elf32_to_cpu(phdr->p_filesz, ehdr), > + elf_size); > + > + /* step to next header */ > + phdr = (struct phdr32 *)(((uint8_t *)phdr) + entsize); > + } > + > + shdr = buffer + elf32_to_cpu(ehdr->e_shoff, ehdr); > + entsize = elf16_to_cpu(ehdr->e_shentsize, ehdr); > + for (i = 0; i < elf16_to_cpu(ehdr->e_shnum, ehdr); i++) { > + if (((uint8_t *)shdr) + entsize > buffer_end) > + return -1; > + > + elf_size = MAX(elf32_to_cpu(shdr->sh_offset, ehdr) + > + elf32_to_cpu(shdr->sh_size, ehdr), > + elf_size); > + > + /* step to next header */ > + shdr = (struct shdr32 *)(((uint8_t *)shdr) + entsize); > + } > + > + elf_size = ROUNDUP(elf_size, 4); > + if (elf_size > buffer_size) > + return -1; > + > + return elf_size; > +} > diff --git a/lib/libelf/elf64.c b/lib/libelf/elf64.c > index 775cdee..824b56f 100644 > --- a/lib/libelf/elf64.c > +++ b/lib/libelf/elf64.c > @@ -20,6 +20,7 @@ > #include <stdio.h> > #include <libelf.h> > #include <byteorder.h> > +#include <helpers.h> > > struct ehdr64 > { > @@ -472,3 +473,58 @@ uint32_t elf_get_eflags_64(void *file_addr) > > return ehdr->e_flags; > } > + > +/* > + * Determine the size of an ELF image that has been loaded into > + * a buffer larger than its size. We search all program headers > + * and sections for the one that shows the farthest extent of the > + * file. > + * @return Return -1 on error, size of file otherwise. > + */ > +long elf_get_file_size64(const void *buffer, const long buffer_size) > +{ > + const struct ehdr64 *ehdr = (const struct ehdr64 *) buffer; > + const uint8_t *buffer_end = buffer + buffer_size; > + const struct phdr64 *phdr; > + const struct shdr64 *shdr; > + long elf_size = -1; > + uint16_t entsize; > + unsigned i; > + > + if (buffer_size < sizeof(struct ehdr) || ehdr->e_ehsize != 64) The same questions here. > + return -1; > + > + phdr = buffer + elf64_to_cpu(ehdr->e_phoff, ehdr); > + entsize = elf16_to_cpu(ehdr->e_phentsize, ehdr); > + for (i = 0; i < elf16_to_cpu(ehdr->e_phnum, ehdr); i++) { > + if (((uint8_t *)phdr) + entsize > buffer_end) > + return -1; > + > + elf_size = MAX(elf64_to_cpu(phdr->p_offset, ehdr) + > + elf64_to_cpu(phdr->p_filesz, ehdr), > + elf_size); > + > + /* step to next header */ > + phdr = (struct phdr64 *)(((uint8_t *)phdr) + entsize); > + } > + > + shdr = buffer + elf64_to_cpu(ehdr->e_shoff, ehdr); > + entsize = elf16_to_cpu(ehdr->e_shentsize, ehdr); > + for (i = 0; i < elf16_to_cpu(ehdr->e_shnum, ehdr); i++) { > + if (((uint8_t *)shdr) + entsize > buffer_end) > + return -1; > + > + elf_size = MAX(elf64_to_cpu(shdr->sh_offset, ehdr) + > + elf64_to_cpu(shdr->sh_size, ehdr), > + elf_size); > + > + /* step to next header */ > + shdr = (struct shdr64 *)(((uint8_t *)shdr) + entsize); > + } > + > + elf_size = ROUNDUP(elf_size, 4); > + if (elf_size > buffer_size) > + return -1; > + > + return elf_size; > +} >
On 5/7/20 9:07 PM, Alexey Kardashevskiy wrote: > > On 02/04/2020 01:57, Stefan Berger wrote: >> From: Stefan Berger <stefanb@linux.ibm.com> >> >> Implement elf_get_file_size to determine the size of an ELF image >> that has been loaded into a buffer much larger than the actual size >> of the original file. We determine the size by searching for the >> farthest offset declared by the ELF headers. >> >> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com> >> --- >> include/helpers.h | 2 ++ >> include/libelf.h | 14 ++++++++++ >> lib/libelf/elf.c | 26 ++++++++++++++++++ >> lib/libelf/elf32.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ >> lib/libelf/elf64.c | 56 ++++++++++++++++++++++++++++++++++++++ >> 5 files changed, 166 insertions(+) >> >> diff --git a/include/helpers.h b/include/helpers.h >> index 47b2674..112184f 100644 >> --- a/include/helpers.h >> +++ b/include/helpers.h >> @@ -51,5 +51,7 @@ extern unsigned long SLOF_get_vtpm_unit(void); >> const typeof(((type *)0)->member)* struct_ptr = (ptr); \ >> (type *)((char *)struct_ptr - offset_of(type, member)); }) >> #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) >> +#define ROUNDUP(x,v) ((((x) + ((v) - 1)) / (v)) * (v)) >> +#define MAX(x,y) ((x) > (y) ? (x) : (y)) >> >> #endif >> diff --git a/include/libelf.h b/include/libelf.h >> index 5fbf279..48ff4d7 100644 >> --- a/include/libelf.h >> +++ b/include/libelf.h >> @@ -96,4 +96,18 @@ void elf_relocate64(void *file_addr, signed long offset); >> >> int elf_forth_claim(void *addr, long size); >> >> +long elf_get_file_size(const void *buffer, const long buffer_size); >> +long elf_get_file_size32(const void *buffer, const long buffer_size); >> +long elf_get_file_size64(const void *buffer, const long buffer_size); >> + >> +#ifdef __BIG_ENDIAN__ >> +#define elf64_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2MSB ? (x) : bswap_64(x)) >> +#define elf32_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2MSB ? (x) : bswap_32(x)) >> +#define elf16_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2MSB ? (x) : bswap_16(x)) >> +#else >> +#define elf64_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2LSB ? (x) : bswap_64(x)) >> +#define elf32_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2LSB ? (x) : bswap_32(x)) >> +#define elf16_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2LSB ? (x) : bswap_16(x)) >> +#endif >> + >> #endif /* __LIBELF_H */ >> diff --git a/lib/libelf/elf.c b/lib/libelf/elf.c >> index 5204bc3..d368454 100644 >> --- a/lib/libelf/elf.c >> +++ b/lib/libelf/elf.c >> @@ -196,3 +196,29 @@ elf_get_base_addr(void *file_addr) >> >> return -1; >> } >> + >> +/** >> + * Get the file size of the ELF image that has been loaded into a >> + * buffer larger than the size of the file >> + * @return The size of the ELF image or < 0 for error >> + */ >> +long elf_get_file_size(const void *buffer, const long buffer_size) >> +{ >> + const struct ehdr *ehdr = (const struct ehdr *)buffer; >> + >> + if (buffer_size < sizeof(struct ehdr)) >> + return -1; >> + >> + /* check if it is an ELF image at all */ >> + if (cpu_to_be32(ehdr->ei_ident) != 0x7f454c46) >> + return -1; >> + >> + switch (ehdr->ei_class) { >> + case 1: >> + return elf_get_file_size32(buffer, buffer_size); >> + case 2: >> + return elf_get_file_size64(buffer, buffer_size); >> + } >> + >> + return -1; >> +} >> diff --git a/lib/libelf/elf32.c b/lib/libelf/elf32.c >> index fea5cf4..7ea85f0 100644 >> --- a/lib/libelf/elf32.c >> +++ b/lib/libelf/elf32.c >> @@ -17,6 +17,7 @@ >> #include <string.h> >> #include <libelf.h> >> #include <byteorder.h> >> +#include <helpers.h> >> >> struct ehdr32 { >> uint32_t ei_ident; >> @@ -50,6 +51,18 @@ struct phdr32 { >> uint32_t p_align; >> }; >> >> +struct shdr32 { >> + uint32_t sh_name; >> + uint32_t sh_type; >> + uint32_t sh_flags; >> + uint32_t sh_addr; >> + uint32_t sh_offset; >> + uint32_t sh_size; >> + uint32_t sh_link; >> + uint32_t sh_info; >> + uint32_t sh_addralign; >> + uint32_t sh_entsize; >> +}; >> >> static struct phdr32* >> get_phdr32(void *file_addr) >> @@ -191,3 +204,58 @@ elf_byteswap_header32(void *file_addr) >> phdr = (struct phdr32 *)(((uint8_t *)phdr) + ehdr->e_phentsize); >> } >> } >> + >> +/* >> + * Determine the size of an ELF image that has been loaded into >> + * a buffer larger than its size. We search all program headers >> + * and sections for the one that shows the farthest extent of the >> + * file. >> + * @return Return -1 on error, size of file otherwise. >> + */ >> +long elf_get_file_size32(const void *buffer, const long buffer_size) >> +{ >> + const struct ehdr32 *ehdr = (const struct ehdr32 *) buffer; >> + const uint8_t *buffer_end = buffer + buffer_size; >> + const struct phdr32 *phdr; >> + const struct shdr32 *shdr; >> + long elf_size = -1; >> + uint16_t entsize; >> + unsigned i; >> + >> + if (buffer_size < sizeof(struct ehdr) || ehdr->e_ehsize != 52) > What is 52? sizeof(struct ehdr32)? Why "!=" rather ">=" ? Right, it's sizeof(struct ehdr32). I will repost this series.
diff --git a/include/helpers.h b/include/helpers.h index 47b2674..112184f 100644 --- a/include/helpers.h +++ b/include/helpers.h @@ -51,5 +51,7 @@ extern unsigned long SLOF_get_vtpm_unit(void); const typeof(((type *)0)->member)* struct_ptr = (ptr); \ (type *)((char *)struct_ptr - offset_of(type, member)); }) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#define ROUNDUP(x,v) ((((x) + ((v) - 1)) / (v)) * (v)) +#define MAX(x,y) ((x) > (y) ? (x) : (y)) #endif diff --git a/include/libelf.h b/include/libelf.h index 5fbf279..48ff4d7 100644 --- a/include/libelf.h +++ b/include/libelf.h @@ -96,4 +96,18 @@ void elf_relocate64(void *file_addr, signed long offset); int elf_forth_claim(void *addr, long size); +long elf_get_file_size(const void *buffer, const long buffer_size); +long elf_get_file_size32(const void *buffer, const long buffer_size); +long elf_get_file_size64(const void *buffer, const long buffer_size); + +#ifdef __BIG_ENDIAN__ +#define elf64_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2MSB ? (x) : bswap_64(x)) +#define elf32_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2MSB ? (x) : bswap_32(x)) +#define elf16_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2MSB ? (x) : bswap_16(x)) +#else +#define elf64_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2LSB ? (x) : bswap_64(x)) +#define elf32_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2LSB ? (x) : bswap_32(x)) +#define elf16_to_cpu(x, ehdr) ((ehdr)->ei_data == ELFDATA2LSB ? (x) : bswap_16(x)) +#endif + #endif /* __LIBELF_H */ diff --git a/lib/libelf/elf.c b/lib/libelf/elf.c index 5204bc3..d368454 100644 --- a/lib/libelf/elf.c +++ b/lib/libelf/elf.c @@ -196,3 +196,29 @@ elf_get_base_addr(void *file_addr) return -1; } + +/** + * Get the file size of the ELF image that has been loaded into a + * buffer larger than the size of the file + * @return The size of the ELF image or < 0 for error + */ +long elf_get_file_size(const void *buffer, const long buffer_size) +{ + const struct ehdr *ehdr = (const struct ehdr *)buffer; + + if (buffer_size < sizeof(struct ehdr)) + return -1; + + /* check if it is an ELF image at all */ + if (cpu_to_be32(ehdr->ei_ident) != 0x7f454c46) + return -1; + + switch (ehdr->ei_class) { + case 1: + return elf_get_file_size32(buffer, buffer_size); + case 2: + return elf_get_file_size64(buffer, buffer_size); + } + + return -1; +} diff --git a/lib/libelf/elf32.c b/lib/libelf/elf32.c index fea5cf4..7ea85f0 100644 --- a/lib/libelf/elf32.c +++ b/lib/libelf/elf32.c @@ -17,6 +17,7 @@ #include <string.h> #include <libelf.h> #include <byteorder.h> +#include <helpers.h> struct ehdr32 { uint32_t ei_ident; @@ -50,6 +51,18 @@ struct phdr32 { uint32_t p_align; }; +struct shdr32 { + uint32_t sh_name; + uint32_t sh_type; + uint32_t sh_flags; + uint32_t sh_addr; + uint32_t sh_offset; + uint32_t sh_size; + uint32_t sh_link; + uint32_t sh_info; + uint32_t sh_addralign; + uint32_t sh_entsize; +}; static struct phdr32* get_phdr32(void *file_addr) @@ -191,3 +204,58 @@ elf_byteswap_header32(void *file_addr) phdr = (struct phdr32 *)(((uint8_t *)phdr) + ehdr->e_phentsize); } } + +/* + * Determine the size of an ELF image that has been loaded into + * a buffer larger than its size. We search all program headers + * and sections for the one that shows the farthest extent of the + * file. + * @return Return -1 on error, size of file otherwise. + */ +long elf_get_file_size32(const void *buffer, const long buffer_size) +{ + const struct ehdr32 *ehdr = (const struct ehdr32 *) buffer; + const uint8_t *buffer_end = buffer + buffer_size; + const struct phdr32 *phdr; + const struct shdr32 *shdr; + long elf_size = -1; + uint16_t entsize; + unsigned i; + + if (buffer_size < sizeof(struct ehdr) || ehdr->e_ehsize != 52) + return -1; + + phdr = buffer + elf32_to_cpu(ehdr->e_phoff, ehdr); + entsize = elf16_to_cpu(ehdr->e_phentsize, ehdr); + for (i = 0; i < elf16_to_cpu(ehdr->e_phnum, ehdr); i++) { + if (((uint8_t *)phdr) + entsize > buffer_end) + return -1; + + elf_size = MAX(elf32_to_cpu(phdr->p_offset, ehdr) + + elf32_to_cpu(phdr->p_filesz, ehdr), + elf_size); + + /* step to next header */ + phdr = (struct phdr32 *)(((uint8_t *)phdr) + entsize); + } + + shdr = buffer + elf32_to_cpu(ehdr->e_shoff, ehdr); + entsize = elf16_to_cpu(ehdr->e_shentsize, ehdr); + for (i = 0; i < elf16_to_cpu(ehdr->e_shnum, ehdr); i++) { + if (((uint8_t *)shdr) + entsize > buffer_end) + return -1; + + elf_size = MAX(elf32_to_cpu(shdr->sh_offset, ehdr) + + elf32_to_cpu(shdr->sh_size, ehdr), + elf_size); + + /* step to next header */ + shdr = (struct shdr32 *)(((uint8_t *)shdr) + entsize); + } + + elf_size = ROUNDUP(elf_size, 4); + if (elf_size > buffer_size) + return -1; + + return elf_size; +} diff --git a/lib/libelf/elf64.c b/lib/libelf/elf64.c index 775cdee..824b56f 100644 --- a/lib/libelf/elf64.c +++ b/lib/libelf/elf64.c @@ -20,6 +20,7 @@ #include <stdio.h> #include <libelf.h> #include <byteorder.h> +#include <helpers.h> struct ehdr64 { @@ -472,3 +473,58 @@ uint32_t elf_get_eflags_64(void *file_addr) return ehdr->e_flags; } + +/* + * Determine the size of an ELF image that has been loaded into + * a buffer larger than its size. We search all program headers + * and sections for the one that shows the farthest extent of the + * file. + * @return Return -1 on error, size of file otherwise. + */ +long elf_get_file_size64(const void *buffer, const long buffer_size) +{ + const struct ehdr64 *ehdr = (const struct ehdr64 *) buffer; + const uint8_t *buffer_end = buffer + buffer_size; + const struct phdr64 *phdr; + const struct shdr64 *shdr; + long elf_size = -1; + uint16_t entsize; + unsigned i; + + if (buffer_size < sizeof(struct ehdr) || ehdr->e_ehsize != 64) + return -1; + + phdr = buffer + elf64_to_cpu(ehdr->e_phoff, ehdr); + entsize = elf16_to_cpu(ehdr->e_phentsize, ehdr); + for (i = 0; i < elf16_to_cpu(ehdr->e_phnum, ehdr); i++) { + if (((uint8_t *)phdr) + entsize > buffer_end) + return -1; + + elf_size = MAX(elf64_to_cpu(phdr->p_offset, ehdr) + + elf64_to_cpu(phdr->p_filesz, ehdr), + elf_size); + + /* step to next header */ + phdr = (struct phdr64 *)(((uint8_t *)phdr) + entsize); + } + + shdr = buffer + elf64_to_cpu(ehdr->e_shoff, ehdr); + entsize = elf16_to_cpu(ehdr->e_shentsize, ehdr); + for (i = 0; i < elf16_to_cpu(ehdr->e_shnum, ehdr); i++) { + if (((uint8_t *)shdr) + entsize > buffer_end) + return -1; + + elf_size = MAX(elf64_to_cpu(shdr->sh_offset, ehdr) + + elf64_to_cpu(shdr->sh_size, ehdr), + elf_size); + + /* step to next header */ + shdr = (struct shdr64 *)(((uint8_t *)shdr) + entsize); + } + + elf_size = ROUNDUP(elf_size, 4); + if (elf_size > buffer_size) + return -1; + + return elf_size; +}