summaryrefslogtreecommitdiff
path: root/src/model/check.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/model/check.c')
-rw-r--r--src/model/check.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/model/check.c b/src/model/check.c
new file mode 100644
index 0000000..cd45f2d
--- /dev/null
+++ b/src/model/check.c
@@ -0,0 +1,104 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <libelfu/libelfu.h>
+
+
+
+static int isOverlapping(size_t off1, size_t sz1, size_t off2, size_t sz2)
+{
+ size_t end1 = off1 + sz1;
+ size_t end2 = off2 + sz2;
+
+ if (off2 >= off1 && off2 < end1) {
+ return 1;
+ } else if (off1 >= off2 && off1 < end2) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+static int cmpScnOffs(const void *ms1, const void *ms2)
+{
+ assert(ms1);
+ assert(ms2);
+
+ ElfuScn *s1 = *(ElfuScn**)ms1;
+ ElfuScn *s2 = *(ElfuScn**)ms2;
+
+ assert(s1);
+ assert(s2);
+
+
+ if (s1->shdr.sh_offset < s2->shdr.sh_offset) {
+ return -1;
+ } else if (s1->shdr.sh_offset == s2->shdr.sh_offset) {
+ return 0;
+ } else /* if (s1->shdr.sh_offset > s2->shdr.sh_offset) */ {
+ return 1;
+ }
+}
+
+
+int elfu_modelCheck(ElfuElf *me)
+{
+ ElfuScn *ms;
+ size_t numSecs;
+ ElfuScn **sortedSecs;
+ size_t i;
+
+ /* Sort sections by offset in file */
+ numSecs = elfu_countSections(me);
+ sortedSecs = malloc(numSecs * sizeof(*sortedSecs));
+ if (!sortedSecs) {
+ fprintf(stderr, "elfu_check: Failed to allocate memory.\n");
+ }
+
+ i = 0;
+ CIRCLEQ_FOREACH(ms, &me->scnList, elem) {
+ sortedSecs[i] = ms;
+ i++;
+ }
+ assert(i = numSecs);
+
+ qsort(sortedSecs, numSecs, sizeof(*sortedSecs), cmpScnOffs);
+
+
+ /* Check for overlapping sections */
+ for (i = 0; i < numSecs - 1; i++) {
+ if (sortedSecs[i]->shdr.sh_offset + elfu_scnSizeFile(&sortedSecs[i]->shdr)
+ > sortedSecs[i+1]->shdr.sh_offset) {
+ fprintf(stderr, "elfu_check: Found overlapping sections: %s and %s.\n",
+ elfu_modelScnName(me, sortedSecs[i]),
+ elfu_modelScnName(me, sortedSecs[i+1]));
+ }
+ }
+
+
+ /* Check for sections overlapping with EHDR */
+ for (i = 0; i < numSecs; i++) {
+ if (sortedSecs[i]->shdr.sh_offset < me->ehdr.e_ehsize) {
+ fprintf(stderr, "elfu_check: Found section overlapping with EHDR: %s.\n",
+ elfu_modelScnName(me, sortedSecs[i]));
+ }
+ }
+
+
+ /* Check for sections overlapping with PHDRs */
+ for (i = 0; i < numSecs; i++) {
+ if (isOverlapping(sortedSecs[i]->shdr.sh_offset,
+ elfu_scnSizeFile(&sortedSecs[i]->shdr),
+ me->ehdr.e_phoff,
+ me->ehdr.e_phentsize * me->ehdr.e_phnum)) {
+ fprintf(stderr, "elfu_check: Found section overlapping with PHDRs: %s.\n",
+ elfu_modelScnName(me, sortedSecs[i]));
+ }
+ }
+
+ free(sortedSecs);
+
+ return 0;
+}