From 9f53067a75931cdb9e46dbbb5a2783277fab88fe Mon Sep 17 00:00:00 2001 From: SangYoun Kwak Date: Mon, 16 Dec 2024 17:10:32 +0900 Subject: [PATCH] Modify to properly use unsigned offset for fseek The fseek gets second parameter(offset) as long type. Since the size of the long type is different depends on the architecture(32/64-bits), any offset value which type is greater than long should be treated with care. To resolve this issue, fseek_offset_u64 function is created and used. Also, offset values which are used in fseek_offset_u64 are re-typed properly. Change-Id: Ic213744ad866a8d4533a8016d59c96703eecc226 Signed-off-by: SangYoun Kwak --- script/postlinker.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/script/postlinker.c b/script/postlinker.c index 15808fd..54dba42 100755 --- a/script/postlinker.c +++ b/script/postlinker.c @@ -3,6 +3,7 @@ #include #include #include +#include #define ELF_FORMAT 0x464c457f @@ -78,6 +79,24 @@ typedef struct { #define STT_OBJECT 1 /* Symbol is a data object */ #define STT_FUNC 2 /* Symbol is a code object */ +static int fseek_offset_u64(FILE *stream, uint64_t offset, int whence) +{ + int ret = 0; + uint64_t offset_left = offset; + + ret = fseek(stream, 0, whence); + if (ret != 0) + return ret; + + for (offset_left = offset; offset_left >= LONG_MAX; offset_left -= LONG_MAX) { + ret = fseek(stream, LONG_MAX, SEEK_CUR); + if (ret != 0) + return ret; + } + + return fseek(stream, (long)offset_left, SEEK_CUR); +} + int PostLinker(char *fileName) { Elf32_Ehdr elfHeader; @@ -91,9 +110,9 @@ int PostLinker(char *fileName) FILE *fp = NULL; int done = 0; - int symbolOff = 0; + Elf32_Word symbolOff = 0; int symEntrySize = 0; - int hashOff = 0; + Elf32_Word hashOff = 0; fp = fopen(fileName, "r+"); @@ -125,7 +144,7 @@ int PostLinker(char *fileName) } /* Get Segment Header Information using ELF Header */ - if (fseek(fp, elfHeader.e_phoff, SEEK_SET) != 0) { + if (fseek_offset_u64(fp, elfHeader.e_phoff, SEEK_SET) != 0) { printf("error[%s] : fseek \n", fileName); exit_status = EXIT_FAILURE; goto finalize; @@ -140,7 +159,7 @@ int PostLinker(char *fileName) /* Get Dynamic segment Information using Segment Header */ for (int i = 0; i < elfHeader.e_phnum; ++i) { if (pSegmentEntries[i].p_type == PT_DYNAMIC) { - if (fseek(fp, pSegmentEntries[i].p_offset, SEEK_SET) != 0) { + if (fseek_offset_u64(fp, pSegmentEntries[i].p_offset, SEEK_SET) != 0) { printf("error[%s] : fseek \n", fileName); exit_status = EXIT_FAILURE; goto finalize; @@ -191,7 +210,13 @@ int PostLinker(char *fileName) } } - if (fseek(fp, hashOff + 4, SEEK_SET) != 0) { + if (hashOff > (UINT32_MAX - 4)) { + printf("error[%s] : fseek \n", fileName); + exit_status = EXIT_FAILURE; + goto finalize; + } + + if (fseek_offset_u64(fp, hashOff + 4, SEEK_SET) != 0) { printf("error[%s] : fseek \n", fileName); exit_status = EXIT_FAILURE; goto finalize; @@ -210,7 +235,7 @@ int PostLinker(char *fileName) goto finalize; } - if (fseek(fp, symbolOff, SEEK_SET) != 0) { + if (fseek_offset_u64(fp, symbolOff, SEEK_SET) != 0) { printf("error[%s] : fseek \n", fileName); exit_status = EXIT_FAILURE; goto finalize; @@ -243,7 +268,7 @@ int PostLinker(char *fileName) goto finalize; } - if (fseek(fp, pSegmentEntries[pos].p_offset, SEEK_SET) != 0) { + if (fseek_offset_u64(fp, pSegmentEntries[pos].p_offset, SEEK_SET) != 0) { printf("error[%s] : fseek \n", fileName); exit_status = EXIT_FAILURE; goto finalize; @@ -255,7 +280,7 @@ int PostLinker(char *fileName) goto finalize; } - if (fseek(fp, symbolOff, SEEK_SET) != 0) { + if (fseek_offset_u64(fp, symbolOff, SEEK_SET) != 0) { printf("error[%s] : fseek \n", fileName); exit_status = EXIT_FAILURE; goto finalize; -- 2.34.1