--- lha-114i/src/header.c +++ lha-114i/src/header.c @@ -538,6 +538,10 @@ /* * filename */ + if (header_size >= 256) { + fprintf(stderr, "Possible buffer overflow hack attack, type #1\n"); + exit(109); + } for (i = 0; i < header_size - 3; i++) hdr->name[i] = (char) get_byte(); hdr->name[header_size - 3] = '\0'; @@ -547,6 +551,10 @@ /* * directory */ + if (header_size >= FILENAME_LENGTH) { + fprintf(stderr, "Possible buffer overflow hack attack, type #2\n"); + exit(110); + } for (i = 0; i < header_size - 3; i++) dirname[i] = (char) get_byte(); dirname[header_size - 3] = '\0'; --- lha-114i/src/lhext.c +++ lha-114i/src/lhext.c @@ -190,8 +190,13 @@ q = (char *) rindex(hdr->name, '/') + 1; } else { + if (is_directory_traversal(q)) { + fprintf(stderr, "Possible directory traversal hack attempt in %s\n", q); + exit(111); + } + if (*q == '/') { - q++; + while (*q == '/') { q++; } /* * if OSK then strip device name */ @@ -419,6 +424,33 @@ return; } +int +is_directory_traversal(char *string) +{ + unsigned int type = 0; /* 0 = new, 1 = only dots, 2 = other chars than dots */ + char *temp; + + temp = string; + + while (*temp != 0) { + if (temp[0] == '/') { + if (type == 1) { return 1; } + type = 0; + temp++; + continue; + } + + if ((temp[0] == '.') && (type < 2)) + type = 1; + if (temp[0] != '.') + type = 2; + + temp++; + } /* while */ + + return (type == 1); +} + /* Local Variables: */ /* mode:c */ /* tab-width:4 */