From d8ae96e2edf356d399ecb8902958558be5d25c6d Mon Sep 17 00:00:00 2001 From: Pentium44 Date: Sat, 10 Apr 2021 19:08:05 -0700 Subject: [PATCH] Cleaned up double free, 'fixed' random decompress segfault --- src/compression.c | 29 +++++++++++++++++------------ src/functions.c | 2 ++ src/tar.c | 32 ++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/compression.c b/src/compression.c index 679cd7f..904ccb0 100644 --- a/src/compression.c +++ b/src/compression.c @@ -44,8 +44,11 @@ uint32_t lz77_compress (uint8_t *uncompressed_text, uint32_t uncompressed_size, look_behind = coding_pos - temp_pointer_pos; look_ahead = coding_pos; for(temp_pointer_length = 0; uncompressed_text[look_ahead++] == uncompressed_text[look_behind++]; ++temp_pointer_length) + { if(temp_pointer_length == pointer_length_max) break; + } + if(temp_pointer_length > pointer_length) { pointer_pos = temp_pointer_pos; @@ -121,30 +124,31 @@ uint32_t ss_compress (const char *filename_in, char *filename_out, uint8_t point if(in == NULL) return 0; uncompressed_size = fsize(in); - uncompressed_text = malloc(uncompressed_size); + uncompressed_text = malloc(uncompressed_size + 20); + // +20 for uncompressed data size sway in algorithm if((uncompressed_size != fread(uncompressed_text, 1, uncompressed_size, in))) { - free(uncompressed_text); + my_free(uncompressed_text); return 0; } fclose(in); - compressed_text = malloc(uncompressed_size * 2); - + compressed_text = malloc((int)(uncompressed_size * 1.25)); + // * 2 for uncompressed size climb on first compress pass compressed_size = lz77_compress(uncompressed_text, uncompressed_size, compressed_text, pointer_length_width); out = fopen(filename_out, "wb"); if(out == NULL) { - free(uncompressed_text); - free(compressed_text); + my_free(uncompressed_text); + my_free(compressed_text); return 0; } if((compressed_size != fwrite(compressed_text, 1, compressed_size, out))) { - free(uncompressed_text); - free(compressed_text); + my_free(uncompressed_text); + my_free(compressed_text); fclose(out); return 0; } @@ -203,8 +207,9 @@ uint32_t ss_decompress // Compressed size comp_size = (int) fsize (ifp); // DM: Compressed data - dm_comp = (uint8_t *) malloc (comp_size); - + dm_comp = (uint8_t *) malloc (comp_size + 10); + // Add some extra memory at the end of malloc comp_size + // Saves dirty archive size sway, WIP if (dm_comp == NULL) // Error? { // Yes - Error exit fprintf (stderr, @@ -234,8 +239,8 @@ uint32_t ss_decompress // Set up decompressed-data buffer. orig_size = (int) *((uint32_t *) dm_comp); - dm_deco = (uint8_t *) malloc (orig_size); - + dm_deco = (uint8_t *) malloc (orig_size + 20); + // +20 to cover byte sway, dirty trick for mem leak if (dm_comp == NULL) // Error? { // Yes my_free (dm_comp); // Release DM diff --git a/src/functions.c b/src/functions.c index 5c7dd9e..978f2ea 100644 --- a/src/functions.c +++ b/src/functions.c @@ -162,9 +162,11 @@ char *process_line(char *line) // perform operation if(tar_extract(fd, archive, 0, NULL, '1') < 0) { // extract entries syn_warn("ss:warn:decompress, error occured"); + return NULL; } tar_free(archive); + close(fd); // don't bother checking for fd < 0 remove(filedecout); diff --git a/src/tar.c b/src/tar.c index 9d9cf91..5706d69 100644 --- a/src/tar.c +++ b/src/tar.c @@ -8,7 +8,6 @@ #define ERROR(fmt, ...) fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__); return -1; // capture errno when erroring #define RC_ERROR(fmt, ...) const int rc = errno; ERROR(fmt, ##__VA_ARGS__); return -1; -#define WRITE_ERROR(fmt, ...) { ERROR(fmt, ##__VA_ARGS__); tar_free(*archive); *archive = NULL; return -1; } #define EXIST_ERROR(fmt, ...) const int rc = errno; if (rc != EEXIST) { ERROR(fmt, ##__VA_ARGS__); return -1; } // force read() to complete @@ -98,7 +97,7 @@ int tar_read(const int fd, struct tar_t ** archive, const char verbosity){ return count; } -int tar_write(const int fd, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity){ +int tar_write(const int fd, struct tar_t **archive, const size_t filecount, const char * files[], const char verbosity){ if (fd < 0){ ERROR("Bad file descriptor"); } @@ -134,7 +133,7 @@ int tar_write(const int fd, struct tar_t ** archive, const size_t filecount, con // write entries first if (write_entries(fd, tar, archive, filecount, files, &offset, verbosity) < 0){ - WRITE_ERROR("Failed to write entries"); + tar_free(*archive); } // write ending data @@ -151,10 +150,15 @@ int tar_write(const int fd, struct tar_t ** archive, const size_t filecount, con return offset; } -void tar_free(struct tar_t * archive){ +void tar_free (struct tar_t *archive) +{ while (archive){ struct tar_t * next = archive -> next; - free(archive); + if(archive != (void *) 0) + { + free(archive); + archive = NULL; + } archive = next; } } @@ -835,13 +839,13 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c } // add new data - struct tar_t ** tar = archive; // current entry + struct tar_t **tar = archive; // current entry for(unsigned int i = 0; i < filecount; i++){ - *tar = malloc(sizeof(struct tar_t)); + *tar = malloc (sizeof (struct tar_t)); // stat file if (format_tar_data(*tar, files[i], verbosity) < 0){ - WRITE_ERROR("Failed to stat %s", files[i]); + tar_free(*tar); } (*tar) -> begin = *offset; @@ -864,13 +868,13 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c // write metadata to (*tar) file if (write_size(fd, (*tar) -> block, 512) != 512){ - WRITE_ERROR("Failed to write metadata to archive"); + tar_free(*tar); } // go through directory DIR * d = opendir(parent); if (!d){ - WRITE_ERROR("Cannot open directory %s", parent); + tar_free(*tar); } struct dirent * dir; @@ -883,7 +887,7 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c // recursively write each subdirectory if (write_entries(fd, &((*tar) -> next), head, 1, (const char **) &path, offset, verbosity) < 0){ - WRITE_ERROR("Recurse error"); + tar_free(*tar); } // go to end of new data @@ -926,7 +930,7 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c // write metadata to (*tar) file if (write_size(fd, (*tar) -> block, 512) != 512){ - WRITE_ERROR("Failed to write metadata to archive"); + tar_free(*tar); } if (((*tar) -> type == REGULAR) || ((*tar) -> type == NORMAL) || ((*tar) -> type == CONTIGUOUS)){ @@ -934,7 +938,7 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c if (!tarred){ int f = open((*tar) -> name, O_RDONLY); if (f < 0){ - WRITE_ERROR("Could not open %s", files[i]); + tar_free(*tar); } int r = 0; @@ -955,7 +959,7 @@ int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, c if (pad != 512){ for(unsigned int j = 0; j < pad; j++){ if (write_size(fd, "\0", 1) != 1){ - WRITE_ERROR("Could not write padding data"); + tar_free(*tar); } } *offset += pad;