CVE-2022-21711: Out-of-bounds Read (CWE-125)
value: elfspirit is an ELF static analysis and injection framework that parses, manipulates, and camouflages ELF files. When analyzing the ELF file format in versions prior to 1.1, there is an out-of-bounds read bug, which can lead to application crashes or information leakage. By constructing a special format ELF file, the information of any address can be leaked. elfspirit version 1.1 contains a patch for this issue.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.1
Published: 2022-01-24T20:15Z
Repository: https://github.com/liyansong2018/elfspirit
Language: C
Files changed: parse.c
Commit date: 2022-01-23 21:17:42 +0800
Commit message: Fix #1 about out-of-bounds

Diff: diff --git a/parse.c b/parse.c
index dbca225..81777b5 100644
--- a/parse.c
+++ b/parse.c
@@ -71,10 +71,21 @@ int flag2str_sh(int flag, char *flag_str) {
         flag_str[0] = 'E';
     
     return 0;
 }
 
+/**
+ * @description: Judge whether the memory address is legal
+ * @param {uint32_t} addr
+ * @param {uint32_t} start
+ * @param {uint32_t} end
+ * @return {*}
+ */
+int validated_offset(uint32_t addr, uint32_t start, uint32_t end){
+    return addr <= end && addr >= start? 0:-1;
+}
+
 int parse(char *elf) {
     int fd;
     struct stat st;
     uint8_t *elf_map;
     int count;
@@ -254,10 +265,14 @@ int parse(char *elf) {
 
         INFO("Section Header Table\n");
         PRINT_SECTION_TITLE("Nr", "Name", "Type", "Addr", "Off", "Size", "Es", "Flg", "Lk", "Inf", "Al");
         for (int i = 0; i < ehdr->e_shnum; i++) {
             name = elf_map + shstrtab.sh_offset + shdr[i].sh_name;
+            if (validated_offset(name, elf_map, elf_map + st.st_size)) {
+                ERROR("Corrupt file format\n");
+                return -1;
+            }
 
             switch (shdr[i].sh_type) {
                 case SHT_NULL:
                     tmp = "SHT_NULL";
                     break;
@@ -900,10 +915,14 @@ int parse(char *elf) {
 
         INFO("Section Header Table\n");
         PRINT_SECTION_TITLE("Nr", "Name", "Type", "Addr", "Off", "Size", "Es", "Flg", "Lk", "Inf", "Al");
         for (int i = 0; i < ehdr->e_shnum; i++) {
             name = elf_map + shstrtab.sh_offset + shdr[i].sh_name;
+            if (validated_offset(name, elf_map, elf_map + st.st_size)) {
+                ERROR("Corrupt file format\n");
+                return -1;
+            }
 
             switch (shdr[i].sh_type) {
                 case SHT_NULL:
                     tmp = "SHT_NULL";
                     break;

Fixed code: /**
 * @description: Judge whether the memory address is legal
 * @param {uint32_t} addr
 * @param {uint32_t} start
 * @param {uint32_t} end
 * @return {*}
 */
int validated_offset(uint32_t addr, uint32_t start, uint32_t end){
    return addr <= end && addr >= start? 0:-1;
}

            if (validated_offset(name, elf_map, elf_map + st.st_size)) {
                ERROR("Corrupt file format\n");
                return -1;
            }
            if (validated_offset(name, elf_map, elf_map + st.st_size)) {
                ERROR("Corrupt file format\n");
                return -1;
            }