summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kexec/kexec-elf-exec.c9
-rw-r--r--kexec/kexec-elf-rel.c9
-rw-r--r--kexec/kexec-elf.c24
-rw-r--r--kexec/kexec-elf.h15
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 @@
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, struct kexec_info *info)
}
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 mem_ehdr *ehdr, const unsigned char *ptr)
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 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info,
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 char *buf, off_t len,
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 *buf, off_t len, struct mem_ehdr *ehdr)
/* 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 char *buf, off_t len,
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 *buf, off_t len, struct mem_ehdr *ehdr)
}
/* 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_t len, struct mem_ehdr *ehdr)
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);