From: Vivek Goyal <[EMAIL PROTECTED]>

o Adding a new parameter to elf functions. This flag can be used to alter
  the function behaviour. Currently only one bit is being used for skipping
  the elf file len check while builing the elf info.

Signed-off-by: Vivek Goyal <[EMAIL PROTECTED]>
---

 kexec/kexec-elf-exec.c |    9 +++++----
 kexec/kexec-elf-rel.c  |    9 +++++----
 kexec/kexec-elf.c      |   24 +++++++++++++++---------
 kexec/kexec-elf.h      |   15 ++++++++++-----
 4 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/kexec/kexec-elf-exec.c b/kexec/kexec-elf-exec.c
index ec00a05..f65a625 100644
--- a/kexec/kexec-elf-exec.c
+++ b/kexec/kexec-elf-exec.c
@@ -11,11 +11,12 @@ #include "kexec-elf.h"
 
 static const int probe_debug = 0;
 
-int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr)
+int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr,
+                               uint32_t flags)
 {
        struct mem_phdr *phdr, *end_phdr;
        int result;
-       result = build_elf_info(buf, len, ehdr);
+       result = build_elf_info(buf, len, ehdr, flags);
        if (result < 0) {
                return result;
        }
@@ -136,11 +137,11 @@ int elf_exec_load(struct mem_ehdr *ehdr,
 }
 
 void elf_exec_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, 
-       const char *buf, off_t len)
+       const char *buf, off_t len, uint32_t flags)
 {
        int result;
        /* Parse the Elf file */
-       result = build_elf_exec_info(buf, len, ehdr);
+       result = build_elf_exec_info(buf, len, ehdr, flags);
        if (result < 0) {
                die("ELF exec parse failed\n");
        }
diff --git a/kexec/kexec-elf-rel.c b/kexec/kexec-elf-rel.c
index ae78a09..4419937 100644
--- a/kexec/kexec-elf-rel.c
+++ b/kexec/kexec-elf-rel.c
@@ -135,10 +135,11 @@ static struct mem_rela elf_rela(struct m
        return rela;
 }
 
-int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr)
+int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr,
+                               uint32_t flags)
 {
        int result;
-       result = build_elf_info(buf, len, ehdr);
+       result = build_elf_info(buf, len, ehdr, flags);
        if (result < 0) {
                return result;
        }
@@ -419,12 +420,12 @@ #endif
 
 void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr,
        const char *buf, off_t len, unsigned long min, unsigned long max,
-       int end)
+       int end, uint32_t flags)
 {
        int result;
 
        /* Parse the Elf file */
-       result = build_elf_rel_info(buf, len, ehdr);
+       result = build_elf_rel_info(buf, len, ehdr, flags);
        if (result < 0) {
                die("ELF rel parse failed\n");
        }
diff --git a/kexec/kexec-elf.c b/kexec/kexec-elf.c
index da2c788..929c79c 100644
--- a/kexec/kexec-elf.c
+++ b/kexec/kexec-elf.c
@@ -368,7 +368,8 @@ static int build_mem_elf64_phdr(const ch
        return 0;
 }
 
-static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr)
+static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr,
+                               uint32_t flags)
 {
        size_t phdr_size, mem_phdr_size;
        int i;
@@ -418,9 +419,11 @@ static int build_mem_phdrs(const char *b
 
                /* Check the program headers to be certain
                 * they are safe to use.
+                * Skip the check if ELF_SKIP_FILESZ_CHECK is set.
                 */
                phdr = &ehdr->e_phdr[i];
-               if ((phdr->p_offset + phdr->p_filesz) > len) {
+               if (!(flags & ELF_SKIP_FILESZ_CHECK)
+                       && (phdr->p_offset + phdr->p_filesz) > len) {
                        /* The segment does not fit in the buffer */
                        if (probe_debug) {
                                fprintf(stderr, "ELF segment not in file\n");
@@ -580,7 +583,8 @@ static int build_mem_elf64_shdr(const ch
        return 0;
 }
 
-static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr)
+static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr,
+                               uint32_t flags)
 {
        size_t shdr_size, mem_shdr_size;
        int i;
@@ -628,11 +632,12 @@ static int build_mem_shdrs(const char *b
                }
                /* Check the section headers to be certain
                 * they are safe to use.
+                * Skip the check if ELF_SKIP_FILESZ_CHECK is set.
                 */
                shdr = &ehdr->e_shdr[i];
-               if ((shdr->sh_type != SHT_NOBITS) &&
-                       ((shdr->sh_offset + shdr->sh_size) > len))
-               {
+               if (!(flags & ELF_SKIP_FILESZ_CHECK)
+                       && (shdr->sh_type != SHT_NOBITS)
+                       && (shdr->sh_offset + shdr->sh_size) > len) {
                        /* The section does not fit in the buffer */
                        if (probe_debug) {
                                fprintf(stderr, "ELF section %d not in file\n",
@@ -729,7 +734,8 @@ void free_elf_info(struct mem_ehdr *ehdr
        memset(ehdr, 0, sizeof(*ehdr));
 }
 
-int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr)
+int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr,
+                       uint32_t flags)
 {
        int result;
        result = build_mem_ehdr(buf, len, ehdr);
@@ -737,14 +743,14 @@ int build_elf_info(const char *buf, off_
                return result;
        }
        if ((ehdr->e_phoff > 0) && (ehdr->e_phnum > 0)) {
-               result = build_mem_phdrs(buf, len, ehdr);
+               result = build_mem_phdrs(buf, len, ehdr, flags);
                if (result < 0) {
                        free_elf_info(ehdr);
                        return result;
                }
        }
        if ((ehdr->e_shoff > 0) && (ehdr->e_shnum > 0)) {
-               result = build_mem_shdrs(buf, len, ehdr);
+               result = build_mem_shdrs(buf, len, ehdr, flags);
                if (result < 0) {
                        free_elf_info(ehdr);
                        return result;
diff --git a/kexec/kexec-elf.h b/kexec/kexec-elf.h
index b7332de..0f09285 100644
--- a/kexec/kexec-elf.h
+++ b/kexec/kexec-elf.h
@@ -82,22 +82,27 @@ typedef struct
        uint32_t n_type;                /* Type of the note.  */
 } ElfNN_Nhdr;
 
+/* Misc flags */
 
+#define ELF_SKIP_FILESZ_CHECK          0x00000001
 
 extern void free_elf_info(struct mem_ehdr *ehdr);
-extern int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr);
-extern int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr 
*ehdr);
-extern int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr 
*ehdr);
+extern int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr,
+                               uint32_t flags);
+extern int build_elf_exec_info(const char *buf, off_t len,
+                               struct mem_ehdr *ehdr, uint32_t flags);
+extern int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr 
*ehdr,
+                               uint32_t flags);
 
 extern int elf_exec_load(struct mem_ehdr *ehdr, struct kexec_info *info);
 extern int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info,
        unsigned long min, unsigned long max, int end);
 
 extern void elf_exec_build_load(struct kexec_info *info, struct mem_ehdr 
*ehdr, 
-       const char *buf, off_t len);
+                               const char *buf, off_t len, uint32_t flags);
 extern void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, 
        const char *buf, off_t len, unsigned long min, unsigned long max, 
-       int end);
+       int end, uint32_t flags);
 
 extern int elf_rel_find_symbol(struct mem_ehdr *ehdr,
        const char *name, struct mem_sym *ret_sym);
_______________________________________________
fastboot mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/fastboot

Reply via email to