Modify to properly use unsigned offset for fseek 00/316700/1 accepted/tizen_unified_x_asan accepted/tizen/unified/20241218.085933 accepted/tizen/unified/x/20241218.212029 accepted/tizen/unified/x/asan/20250113.002234
authorSangYoun Kwak <sy.kwak@samsung.com>
Mon, 16 Dec 2024 08:10:32 +0000 (17:10 +0900)
committerSangYoun Kwak <sy.kwak@samsung.com>
Tue, 17 Dec 2024 06:07:08 +0000 (15:07 +0900)
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 <sy.kwak@samsung.com>
script/postlinker.c

index 15808fd3d89d7f55f56a854e9bc40502896c2bce..54dba42c0c8adc03bc20f4fe88630fb8fd2ebe76 100755 (executable)
@@ -3,6 +3,7 @@
 #include <errno.h>
 #include <string.h>
 #include <stdint.h>
+#include <limits.h>
 
 #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 <pSegmentEntries>\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 <DynEntries>\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 <symEntryCnt>\n", fileName);
+               exit_status = EXIT_FAILURE;
+               goto finalize;
+       }
+
+       if (fseek_offset_u64(fp, hashOff + 4, SEEK_SET) != 0) {
                printf("error[%s] : fseek <symEntryCnt>\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 <pMapSymbolTable>\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 <DynEntries>\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 <pMapSymbolTable>\n", fileName);
                exit_status = EXIT_FAILURE;
                goto finalize;