Vulnerability: 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.
Vulnerability ID: CVE-2022-21711
CWE: CWE-125
Severity score: 4.9
Project: https://github.com/liyansong2018/elfspirit
Published: 2022-01-24
File: parse.c
Commit message: Fix #1 about out-of-bounds
Commit author: liyansong2018

Vulnerable version (before fix):
 int flag2str_sh(int flag, char *flag_str) {     return 0; }  int parse(char *elf) {     int fd;     struct stat st; int parse(char *elf) {         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;              switch (shdr[i].sh_type) {                 case SHT_NULL: int parse(char *elf) {         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;              switch (shdr[i].sh_type) {                 case SHT_NULL:

Fixed version (after fix):
 int flag2str_sh(int flag, char *flag_str) {     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; int parse(char *elf) {         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: int parse(char *elf) {         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:

Patch:
patch: @@ -73,6 +73,17 @@ int flag2str_sh(int flag, char *flag_str) {
     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;
@@ -256,6 +267,10 @@ int parse(char *elf) {
         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:
@@ -902,6 +917,10 @@ int parse(char *elf) {
         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:
path: parse.c