#include <errno.h>
#include <string.h>
#include <stdint.h>
+#include <limits.h>
#define ELF_FORMAT 0x464c457f
#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;
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+");
}
/* 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;
/* 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;
}
}
- 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;
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;
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;
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;