From d212cc111544e456d29abc692e2513edf8ae1456 Mon Sep 17 00:00:00 2001
From: Con Kolivas <kernel@kolivas.org>
Date: Wed, 16 May 2018 14:12:22 +1000
Subject: [PATCH] Use dealloc() wrapper to minimise risk of local use after
 free.

---
 liblrzip.c      |  24 +++++-----
 lrzip.c         |  32 +++++++-------
 lrzip_private.h |   7 ++-
 runzip.c        |  14 +++---
 rzip.c          |  63 +++++++++++++-------------
 stream.c        | 115 ++++++++++++++++++++++++------------------------
 6 files changed, 130 insertions(+), 125 deletions(-)

diff --git a/liblrzip.c b/liblrzip.c
index 04333f38..67d6bba0 100644
--- a/liblrzip.c
+++ b/liblrzip.c
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2012-2016 Con Kolivas
+   Copyright (C) 2012-2016,2018 Con Kolivas
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -155,10 +155,10 @@ void lrzip_free(Lrzip *lr)
 		return;
 	rzip_control_free(lr->control);
 	for (x = 0; x < lr->infilename_idx; x++)
-		free(lr->infilenames[x]);
-	free(lr->infilenames);
-	free(lr->infiles);
-	free(lr);
+		dealloc(lr->infilenames[x]);
+	dealloc(lr->infilenames);
+	dealloc(lr->infiles);
+	dealloc(lr);
 }
 
 Lrzip *lrzip_new(Lrzip_Mode mode)
@@ -354,7 +354,7 @@ void lrzip_files_clear(Lrzip *lr)
 {
 	if ((!lr) || (!lr->infile_buckets))
 		return;
-	free(lr->infiles);
+	dealloc(lr->infiles);
 	lr->infiles = NULL;
 }
 
@@ -403,7 +403,7 @@ bool lrzip_filename_del(Lrzip *lr, const char *file)
 			return true; /* not found */
 		if (strcmp(lr->infilenames[x], file))
 			continue; /* not a match */
-		free(lr->infilenames[x]);
+		dealloc(lr->infilenames[x]);
 		break;
 	}
 	/* update index */
@@ -427,8 +427,8 @@ void lrzip_filenames_clear(Lrzip *lr)
 	if ((!lr) || (!lr->infilename_buckets))
 		return;
 	for (x = 0; x < lr->infilename_idx; x++)
-		free(lr->infilenames[x]);
-	free(lr->infilenames);
+		dealloc(lr->infilenames[x]);
+	dealloc(lr->infilenames);
 	lr->infilenames = NULL;
 }
 
@@ -436,7 +436,7 @@ void lrzip_suffix_set(Lrzip *lr, const char *suffix)
 {
 	if ((!lr) || (!suffix) || (!suffix[0]))
 		return;
-	free(lr->control->suffix);
+	dealloc(lr->control->suffix);
 	lr->control->suffix = strdup(suffix);
 }
 
@@ -454,7 +454,7 @@ void lrzip_outdir_set(Lrzip *lr, const char *dir)
 	size_t len;
 	if ((!lr) || (!dir) || (!dir[0]))
 		return;
-	free(lr->control->outdir);
+	dealloc(lr->control->outdir);
 	slash = strrchr(dir, '/');
 	if (slash && (slash[1] == 0)) {
 		lr->control->outdir = strdup(dir);
@@ -501,7 +501,7 @@ void lrzip_outfilename_set(Lrzip *lr, const char *file)
 		return;
 	if (lr->control->outname && file && (!strcmp(lr->control->outname, file)))
 		return;
-	free(lr->control->outname);
+	dealloc(lr->control->outname);
 	lr->control->outname = file ? strdup(file) : NULL;
 }
 
diff --git a/lrzip.c b/lrzip.c
index 6db70b29..5c044eb0 100644
--- a/lrzip.c
+++ b/lrzip.c
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2006-2016 Con Kolivas
+   Copyright (C) 2006-2016,2018 Con Kolivas
    Copyright (C) 2011 Peter Hyman
    Copyright (C) 1998-2003 Andrew Tridgell
 
@@ -438,7 +438,7 @@ int open_tmpinfile(rzip_control *control)
 
 	/* Try the current directory */
 	if (fd_in == -1) {
-		free(control->infile);
+		dealloc(control->infile);
 		control->infile = malloc(16);
 		if (unlikely(!control->infile))
 			fatal_return(("Failed to allocate infile name\n"), -1);
@@ -448,7 +448,7 @@ int open_tmpinfile(rzip_control *control)
 
 	/* Use /tmp if nothing is writeable so far */
 	if (fd_in == -1) {
-		free(control->infile);
+		dealloc(control->infile);
 		control->infile = malloc(20);
 		if (unlikely(!control->infile))
 			fatal_return(("Failed to allocate infile name\n"), -1);
@@ -543,7 +543,7 @@ static bool open_tmpoutbuf(rzip_control *control)
 void close_tmpoutbuf(rzip_control *control)
 {
 	control->flags &= ~FLAG_TMP_OUTBUF;
-	free(control->tmp_outbuf);
+	dealloc(control->tmp_outbuf);
 	if (!BITS32)
 		control->usable_ram = control->maxram += control->ramsize / 18;
 }
@@ -576,7 +576,7 @@ bool clear_tmpinfile(rzip_control *control)
 void close_tmpinbuf(rzip_control *control)
 {
 	control->flags &= ~FLAG_TMP_INBUF;
-	free(control->tmp_inbuf);
+	dealloc(control->tmp_inbuf);
 	if (!BITS32)
 		control->usable_ram = control->maxram += control->ramsize / 18;
 }
@@ -613,8 +613,8 @@ static bool get_hash(rzip_control *control, int make_hash)
 	control->hash = calloc(HASH_LEN, 1);
 	if (unlikely(!passphrase || !testphrase || !control->salt_pass || !control->hash)) {
 		fatal("Failed to calloc encrypt buffers in compress_file\n");
-		free(testphrase);
-		free(passphrase);
+		dealloc(testphrase);
+		dealloc(passphrase);
 		return false;
 	}
 	mlock(passphrase, PASS_LEN);
@@ -628,8 +628,8 @@ static bool get_hash(rzip_control *control, int make_hash)
 			fatal("Supplied password was null!");
 			munlock(passphrase, PASS_LEN);
 			munlock(testphrase, PASS_LEN);
-			free(testphrase);
-			free(passphrase);
+			dealloc(testphrase);
+			dealloc(passphrase);
 			release_hashes(control);
 			return false;
 		}
@@ -666,8 +666,8 @@ static bool get_hash(rzip_control *control, int make_hash)
 	memset(passphrase, 0, PASS_LEN);
 	munlock(passphrase, PASS_LEN);
 	munlock(testphrase, PASS_LEN);
-	free(testphrase);
-	free(passphrase);
+	dealloc(testphrase);
+	dealloc(passphrase);
 	return true;
 }
 
@@ -677,8 +677,8 @@ static void release_hashes(rzip_control *control)
 	memset(control->hash, 0, SALT_LEN);
 	munlock(control->salt_pass, PASS_LEN);
 	munlock(control->hash, HASH_LEN);
-	free(control->salt_pass);
-	free(control->hash);
+	dealloc(control->salt_pass);
+	dealloc(control->hash);
 }
 
 /*
@@ -877,7 +877,7 @@ bool decompress_file(rzip_control *control)
 	if (ENCRYPT)
 		release_hashes(control);
 
-	free(control->outfile);
+	dealloc(control->outfile);
 	return true;
 }
 
@@ -1155,7 +1155,7 @@ bool get_fileinfo(rzip_control *control)
 			fatal_return(("Failed to close fd_in in get_fileinfo\n"), false);
 
 out:
-	free(control->outfile);
+	dealloc(control->outfile);
 	return true;
 error:
 	if (!STDIN && ! IS_FROM_FILE) close(fd_in);
@@ -1290,7 +1290,7 @@ bool compress_file(rzip_control *control)
 			fatal_return(("Failed to unlink %s\n", control->infile), false);
 	}
 
-	free(control->outfile);
+	dealloc(control->outfile);
 	return true;
 error:
 	if (! IS_FROM_FILE && STDIN && (fd_in > 0))
diff --git a/lrzip_private.h b/lrzip_private.h
index a83d747b..6c0acd44 100644
--- a/lrzip_private.h
+++ b/lrzip_private.h
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2006-2016 Con Kolivas
+   Copyright (C) 2006-2016,2018 Con Kolivas
    Copyright (C) 2011 Peter Hyman
    Copyright (C) 1998-2003 Andrew Tridgell
 
@@ -266,6 +266,11 @@ typedef sem_t cksem_t;
 # define PAGE_SIZE (4096)
 #endif
 
+#define dealloc(ptr) do { \
+	free(ptr); \
+	ptr = NULL; \
+} while (0)
+
 /* Determine how many times to hash the password when encrypting, based on
  * the date such that we increase the number of loops according to Moore's
  * law relative to when the data is encrypted. It is then stored as a two
diff --git a/runzip.c b/runzip.c
index cccdcdd8..61ca2ef1 100644
--- a/runzip.c
+++ b/runzip.c
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2006-2016 Con Kolivas
+   Copyright (C) 2006-2016,2018 Con Kolivas
    Copyright (C) 1998-2003 Andrew Tridgell
 
    This program is free software; you can redistribute it and/or modify
@@ -161,12 +161,12 @@ static i64 unzip_literal(rzip_control *control, void *ss, i64 len, uint32 *cksum
 
 	stream_read = read_stream(control, ss, 1, buf, len);
 	if (unlikely(stream_read == -1 )) {
-		free(buf);
+		dealloc(buf);
 		fatal_return(("Failed to read_stream in unzip_literal\n"), -1);
 	}
 
 	if (unlikely(write_1g(control, buf, (size_t)stream_read) != (ssize_t)stream_read)) {
-		free(buf);
+		dealloc(buf);
 		fatal_return(("Failed to write literal buffer of size %lld\n", stream_read), -1);
 	}
 
@@ -175,7 +175,7 @@ static i64 unzip_literal(rzip_control *control, void *ss, i64 len, uint32 *cksum
 	if (!NO_MD5)
 		md5_process_bytes(buf, stream_read, &control->ctx);
 
-	free(buf);
+	dealloc(buf);
 	return stream_read;
 }
 
@@ -221,11 +221,11 @@ static i64 unzip_match(rzip_control *control, void *ss, i64 len, uint32 *cksum,
 		n = MIN(len, offset);
 
 		if (unlikely(read_fdhist(control, off_buf, (size_t)n) != (ssize_t)n)) {
-			free(buf);
+			dealloc(buf);
 			fatal_return(("Failed to read %d bytes in unzip_match\n", n), -1);
 		}
 		if (unlikely(write_1g(control, off_buf, (size_t)n) != (ssize_t)n)) {
-			free(buf);
+			dealloc(buf);
 			fatal_return(("Failed to write %d bytes in unzip_match\n", n), -1);
 		}
 
@@ -239,7 +239,7 @@ static i64 unzip_match(rzip_control *control, void *ss, i64 len, uint32 *cksum,
 		total += n;
 	}
 
-	free(buf);
+	dealloc(buf);
 
 	return total;
 }
diff --git a/rzip.c b/rzip.c
index 2bd444f4..664b3dec 100644
--- a/rzip.c
+++ b/rzip.c
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2006-2016 Con Kolivas
+   Copyright (C) 2006-2016,2018 Con Kolivas
    Copyright (C) 1998 Andrew Tridgell
 
    Modified to use flat hash, memory limit and variable hash culling
@@ -588,7 +588,7 @@ static void *cksumthread(void *data)
 	*control->checksum.cksum = CrcUpdate(*control->checksum.cksum, control->checksum.buf, control->checksum.len);
 	if (!NO_MD5)
 		md5_process_bytes(control->checksum.buf, control->checksum.len, &control->ctx);
-	free(control->checksum.buf);
+	dealloc(control->checksum.buf);
 	cksem_post(control, &control->cksumsem);
 	return NULL;
 }
@@ -765,7 +765,7 @@ static inline void hash_search(rzip_control *control, struct rzip_state *st,
 		st->cksum = CrcUpdate(st->cksum, control->checksum.buf, cksum_remains);
 		if (!NO_MD5)
 			md5_process_bytes(control->checksum.buf, cksum_remains, &control->ctx);
-		free(control->checksum.buf);
+		dealloc(control->checksum.buf);
 		cksem_post(control, &control->cksumsem);
 	} else {
 		cksem_wait(control, &control->cksumsem);
@@ -937,13 +937,13 @@ void rzip_fd(rzip_control *control, int fd_in, int fd_out)
 
 	if (LZO_COMPRESS) {
 		if (unlikely(lzo_init() != LZO_E_OK)) {
-			free(st);
+			dealloc(st);
 			failure("lzo_init() failed\n");
 		}
 	}
 
 	if (unlikely(fstat(fd_in, &s))) {
-		free(st);
+		dealloc(st);
 		failure("Failed to stat fd_in in rzip_fd\n");
 	}
 
@@ -958,7 +958,7 @@ void rzip_fd(rzip_control *control, int fd_in, int fd_out)
 		* compressed file, based on the compressed file being as large as the
 		* uncompressed file. */
 		if (unlikely(fstatvfs(fd_out, &fbuf))) {
-			free(st);
+			dealloc(st);
 			failure("Failed to fstatvfs in compress_file\n");
 		}
 		free_space = (i64)fbuf.f_bsize * (i64)fbuf.f_bavail;
@@ -966,7 +966,7 @@ void rzip_fd(rzip_control *control, int fd_in, int fd_out)
 			if (FORCE_REPLACE)
 				print_err("Warning, possibly inadequate free space detected, but attempting to compress due to -f option being used.\n");
 			else {
-				free(st);
+				dealloc(st);
 				failure("Possibly inadequate free space to compress file, use -f to override.\n");
 			}
 		}
@@ -1041,16 +1041,16 @@ void rzip_fd(rzip_control *control, int fd_in, int fd_out)
 			if (sb->buf_low == MAP_FAILED) {
 				if (unlikely(errno != ENOMEM)) {
 					close_streamout_threads(control);
-					free(st->hash_table);
-					free(st);
+					dealloc(st->hash_table);
+					dealloc(st);
 					failure("Failed to mmap %s\n", control->infile);
 				}
 				st->mmap_size = st->mmap_size / 10 * 9;
 				round_to_page(&st->mmap_size);
 				if (unlikely(!st->mmap_size)) {
 					close_streamout_threads(control);
-					free(st->hash_table);
-					free(st);
+					dealloc(st->hash_table);
+					dealloc(st);
 					failure("Unable to mmap any ram\n");
 				}
 				goto retry;
@@ -1063,16 +1063,16 @@ void rzip_fd(rzip_control *control, int fd_in, int fd_out)
 			if (sb->buf_low == MAP_FAILED) {
 				if (unlikely(errno != ENOMEM)) {
 					close_streamout_threads(control);
-					free(st->hash_table);
-					free(st);
+					dealloc(st->hash_table);
+					dealloc(st);
 					failure("Failed to mmap %s\n", control->infile);
 				}
 				st->mmap_size = st->mmap_size / 10 * 9;
 				round_to_page(&st->mmap_size);
 				if (unlikely(!st->mmap_size)) {
 					close_streamout_threads(control);
-					free(st->hash_table);
-					free(st);
+					dealloc(st->hash_table);
+					dealloc(st);
 					failure("Unable to mmap any ram\n");
 				}
 				goto retry;
@@ -1159,16 +1159,16 @@ void rzip_fd(rzip_control *control, int fd_in, int fd_out)
 		len -= st->chunk_size;
 		if (unlikely(len > 0 && control->eof)) {
 			close_streamout_threads(control);
-			free(st->hash_table);
-			free(st);
+			dealloc(st->hash_table);
+			dealloc(st);
 			failure("Wrote EOF to file yet chunk_size was shrunk, corrupting archive.\n");
 		}
 	}
 
 	if (likely(st->hash_table))
-		free(st->hash_table);
+		dealloc(st->hash_table);
 	if (unlikely(!close_streamout_threads(control))) {
-		free(st);
+		dealloc(st);
 		failure("Failed to close_streamout_threads in rzip_fd\n");
 	}
 
@@ -1184,18 +1184,18 @@ void rzip_fd(rzip_control *control, int fd_in, int fd_out)
 		/* When encrypting data, we encrypt the MD5 value as well */
 		if (ENCRYPT)
 			if (unlikely(!lrz_encrypt(control, control->md5_resblock, MD5_DIGEST_SIZE, control->salt_pass))) {
-				free(st);
+				dealloc(st);
 				failure("Failed to lrz_encrypt in rzip_fd\n");
 			}
 		if (unlikely(write_1g(control, control->md5_resblock, MD5_DIGEST_SIZE) != MD5_DIGEST_SIZE)) {
-			free(st);
+			dealloc(st);
 			failure("Failed to write md5 in rzip_fd\n");
 		}
 	}
 
 	if (TMP_OUTBUF) {
 		if (unlikely(!flush_tmpoutbuf(control))) {
-			free(st);
+			dealloc(st);
 			failure("Failed to flush_tmpoutbuf in rzip_fd\n");
 		}
 	}
@@ -1225,7 +1225,7 @@ void rzip_fd(rzip_control *control, int fd_in, int fd_out)
 	print_progress("Compression Ratio: %.3f. Average Compression Speed: %6.3fMB/s.\n",
 		       1.0 * s.st_size / s2.st_size, chunkmbs);
 
-	free(st);
+	dealloc(st);
 }
 
 void rzip_control_free(rzip_control *control)
@@ -1234,15 +1234,16 @@ void rzip_control_free(rzip_control *control)
 	if (!control)
 		return;
 
-	free(control->tmpdir);
-	free(control->outname);
-	free(control->outdir);
-	if (control->suffix && control->suffix[0]) free(control->suffix);
+	dealloc(control->tmpdir);
+	dealloc(control->outname);
+	dealloc(control->outdir);
+	if (control->suffix && control->suffix[0])
+		dealloc(control->suffix);
 
 	for (x = 0; x < control->sinfo_idx; x++) {
-		free(control->sinfo_queue[x]->s);
-		free(control->sinfo_queue[x]);
+		dealloc(control->sinfo_queue[x]->s);
+		dealloc(control->sinfo_queue[x]);
 	}
-	free(control->sinfo_queue);
-	free(control);
+	dealloc(control->sinfo_queue);
+	dealloc(control);
 }
diff --git a/stream.c b/stream.c
index 96efd392..317b95b3 100644
--- a/stream.c
+++ b/stream.c
@@ -1,6 +1,6 @@
 /*
+   Copyright (C) 2006-2016,2018 Con Kolivas
    Copyright (C) 2011 Serge Belyshev
-   Copyright (C) 2006-2016 Con Kolivas
    Copyright (C) 2011 Peter Hyman
    Copyright (C) 1998 Andrew Tridgell
 
@@ -187,12 +187,12 @@ static int zpaq_compress_buf(rzip_control *control, struct compress_thread *cthr
 	if (unlikely(c_len >= cthread->c_len)) {
 		print_maxverbose("Incompressible block\n");
 		/* Incompressible, leave as CTYPE_NONE */
-		free(c_buf);
+		dealloc(c_buf);
 		return 0;
 	}
 
 	cthread->c_len = c_len;
-	free(cthread->s_buf);
+	dealloc(cthread->s_buf);
 	cthread->s_buf = c_buf;
 	cthread->c_type = CTYPE_ZPAQ;
 	return 0;
@@ -223,12 +223,12 @@ static int bzip2_compress_buf(rzip_control *control, struct compress_thread *cth
 	if (bzip2_ret == BZ_OUTBUFF_FULL) {
 		print_maxverbose("Incompressible block\n");
 		/* Incompressible, leave as CTYPE_NONE */
-		free(c_buf);
+		dealloc(c_buf);
 		return 0;
 	}
 
 	if (unlikely(bzip2_ret != BZ_OK)) {
-		free(c_buf);
+		dealloc(c_buf);
 		print_maxverbose("BZ2 compress failed\n");
 		return -1;
 	}
@@ -236,12 +236,12 @@ static int bzip2_compress_buf(rzip_control *control, struct compress_thread *cth
 	if (unlikely(dlen >= cthread->c_len)) {
 		print_maxverbose("Incompressible block\n");
 		/* Incompressible, leave as CTYPE_NONE */
-		free(c_buf);
+		dealloc(c_buf);
 		return 0;
 	}
 
 	cthread->c_len = dlen;
-	free(cthread->s_buf);
+	dealloc(cthread->s_buf);
 	cthread->s_buf = c_buf;
 	cthread->c_type = CTYPE_BZIP2;
 	return 0;
@@ -268,12 +268,12 @@ static int gzip_compress_buf(rzip_control *control, struct compress_thread *cthr
 	if (gzip_ret == Z_BUF_ERROR) {
 		print_maxverbose("Incompressible block\n");
 		/* Incompressible, leave as CTYPE_NONE */
-		free(c_buf);
+		dealloc(c_buf);
 		return 0;
 	}
 
 	if (unlikely(gzip_ret != Z_OK)) {
-		free(c_buf);
+		dealloc(c_buf);
 		print_maxverbose("compress2 failed\n");
 		return -1;
 	}
@@ -281,12 +281,12 @@ static int gzip_compress_buf(rzip_control *control, struct compress_thread *cthr
 	if (unlikely((i64)dlen >= cthread->c_len)) {
 		print_maxverbose("Incompressible block\n");
 		/* Incompressible, leave as CTYPE_NONE */
-		free(c_buf);
+		dealloc(c_buf);
 		return 0;
 	}
 
 	cthread->c_len = dlen;
-	free(cthread->s_buf);
+	dealloc(cthread->s_buf);
 	cthread->s_buf = c_buf;
 	cthread->c_type = CTYPE_GZIP;
 	return 0;
@@ -344,7 +344,7 @@ static int lzma_compress_buf(rzip_control *control, struct compress_thread *cthr
 				break;
 		}
 		/* can pass -1 if not compressible! Thanks Lasse Collin */
-		free(c_buf);
+		dealloc(c_buf);
 		if (lzma_ret == SZ_ERROR_MEM) {
 			if (lzma_level > 1) {
 				lzma_level--;
@@ -364,7 +364,7 @@ static int lzma_compress_buf(rzip_control *control, struct compress_thread *cthr
 	if (unlikely((i64)dlen >= cthread->c_len)) {
 		/* Incompressible, leave as CTYPE_NONE */
 		print_maxverbose("Incompressible block\n");
-		free(c_buf);
+		dealloc(c_buf);
 		return 0;
 	}
 
@@ -381,7 +381,7 @@ static int lzma_compress_buf(rzip_control *control, struct compress_thread *cthr
 	unlock_mutex(control, &control->control_lock);
 
 	cthread->c_len = dlen;
-	free(cthread->s_buf);
+	dealloc(cthread->s_buf);
 	cthread->s_buf = c_buf;
 	cthread->c_type = CTYPE_LZMA;
 	return 0;
@@ -415,16 +415,16 @@ static int lzo_compress_buf(rzip_control *control, struct compress_thread *cthre
 	if (dlen >= in_len){
 		/* Incompressible, leave as CTYPE_NONE */
 		print_maxverbose("Incompressible block\n");
-		free(c_buf);
+		dealloc(c_buf);
 		goto out_free;
 	}
 
 	cthread->c_len = dlen;
-	free(cthread->s_buf);
+	dealloc(cthread->s_buf);
 	cthread->s_buf = c_buf;
 	cthread->c_type = CTYPE_LZO;
 out_free:
-	free(wrkmem);
+	dealloc(wrkmem);
 	return ret;
 }
 
@@ -458,7 +458,7 @@ static int zpaq_decompress_buf(rzip_control *control __UNUSED__, struct uncomp_t
 		ret = -1;
 	}
 
-	free(c_buf);
+	dealloc(c_buf);
 out:
 	if (ret == -1)
 		ucthread->s_buf = c_buf;
@@ -482,7 +482,7 @@ static int bzip2_decompress_buf(rzip_control *control __UNUSED__, struct uncomp_
 	bzerr = BZ2_bzBuffToBuffDecompress((char*)ucthread->s_buf, &dlen, (char*)c_buf, ucthread->c_len, 0, 0);
 	if (unlikely(bzerr != BZ_OK)) {
 		print_err("Failed to decompress buffer - bzerr=%d\n", bzerr);
-		free(ucthread->s_buf);
+		dealloc(ucthread->s_buf);
 		ucthread->s_buf = c_buf;
 		ret = -1;
 		goto out;
@@ -493,7 +493,7 @@ static int bzip2_decompress_buf(rzip_control *control __UNUSED__, struct uncomp_
 		ret = -1;
 	}
 
-	free(c_buf);
+	dealloc(c_buf);
 out:
 	if (ret == -1)
 		ucthread->s_buf = c_buf;
@@ -517,7 +517,7 @@ static int gzip_decompress_buf(rzip_control *control __UNUSED__, struct uncomp_t
 	gzerr = uncompress(ucthread->s_buf, &dlen, c_buf, ucthread->c_len);
 	if (unlikely(gzerr != Z_OK)) {
 		print_err("Failed to decompress buffer - gzerr=%d\n", gzerr);
-		free(ucthread->s_buf);
+		dealloc(ucthread->s_buf);
 		ucthread->s_buf = c_buf;
 		ret = -1;
 		goto out;
@@ -528,7 +528,7 @@ static int gzip_decompress_buf(rzip_control *control __UNUSED__, struct uncomp_t
 		ret = -1;
 	}
 
-	free(c_buf);
+	dealloc(c_buf);
 out:
 	if (ret == -1)
 		ucthread->s_buf = c_buf;
@@ -555,7 +555,7 @@ static int lzma_decompress_buf(rzip_control *control, struct uncomp_thread *ucth
 	lzmaerr = LzmaUncompress(ucthread->s_buf, &dlen, c_buf, &c_len, control->lzma_properties, 5);
 	if (unlikely(lzmaerr)) {
 		print_err("Failed to decompress buffer - lzmaerr=%d\n", lzmaerr);
-		free(ucthread->s_buf);
+		dealloc(ucthread->s_buf);
 		ucthread->s_buf = c_buf;
 		ret = -1;
 		goto out;
@@ -566,7 +566,7 @@ static int lzma_decompress_buf(rzip_control *control, struct uncomp_thread *ucth
 		ret = -1;
 	}
 
-	free(c_buf);
+	dealloc(c_buf);
 out:
 	if (ret == -1)
 		ucthread->s_buf = c_buf;
@@ -590,7 +590,7 @@ static int lzo_decompress_buf(rzip_control *control __UNUSED__, struct uncomp_th
 	lzerr = lzo1x_decompress((uchar*)c_buf, ucthread->c_len, (uchar*)ucthread->s_buf, &dlen, NULL);
 	if (unlikely(lzerr != LZO_E_OK)) {
 		print_err("Failed to decompress buffer - lzerr=%d\n", lzerr);
-		free(ucthread->s_buf);
+		dealloc(ucthread->s_buf);
 		ucthread->s_buf = c_buf;
 		ret = -1;
 		goto out;
@@ -601,7 +601,7 @@ static int lzo_decompress_buf(rzip_control *control __UNUSED__, struct uncomp_th
 		ret = -1;
 	}
 
-	free(c_buf);
+	dealloc(c_buf);
 out:
 	if (ret == -1)
 		ucthread->s_buf = c_buf;
@@ -903,7 +903,7 @@ bool prepare_streamout_threads(rzip_control *control)
 
 	cthread = calloc(sizeof(struct compress_thread), control->threads);
 	if (unlikely(!cthread)) {
-		free(threads);
+		dealloc(threads);
 		fatal_return(("Unable to calloc cthread in prepare_streamout_threads\n"), false);
 	}
 
@@ -927,8 +927,8 @@ bool close_streamout_threads(rzip_control *control)
 		if (++close_thread == control->threads)
 			close_thread = 0;
 	}
-	free(cthread);
-	free(threads);
+	dealloc(cthread);
+	dealloc(threads);
 	return true;
 }
 
@@ -954,7 +954,7 @@ void *open_stream_out(rzip_control *control, int f, unsigned int n, i64 chunk_li
 
 	sinfo->s = calloc(sizeof(struct stream), n);
 	if (unlikely(!sinfo->s)) {
-		free(sinfo);
+		dealloc(sinfo);
 		return NULL;
 	}
 
@@ -1001,13 +1001,13 @@ void *open_stream_out(rzip_control *control, int f, unsigned int n, i64 chunk_li
 		char *testmalloc2 = malloc(limit);
 
 		if (!testmalloc2) {
-			free(testmalloc);
+			dealloc(testmalloc);
 			limit = limit / 10 * 9;
 			goto retest_malloc;
 		}
-		free(testmalloc2);
+		dealloc(testmalloc2);
 	}
-	free(testmalloc);
+	dealloc(testmalloc);
 	print_maxverbose("Succeeded in testing %lld sized malloc for back end compression\n", testsize);
 
 	/* Make the bufsize no smaller than STREAM_BUFSIZE. Round up the
@@ -1026,8 +1026,8 @@ void *open_stream_out(rzip_control *control, int f, unsigned int n, i64 chunk_li
 		sinfo->s[i].buf = calloc(sinfo->bufsize , 1);
 		if (unlikely(!sinfo->s[i].buf)) {
 			fatal("Unable to malloc buffer of size %lld in open_stream_out\n", sinfo->bufsize);
-			free(sinfo->s);
-			free(sinfo);
+			dealloc(sinfo->s);
+			dealloc(sinfo);
 			return NULL;
 		}
 	}
@@ -1081,8 +1081,8 @@ void *open_stream_in(rzip_control *control, int f, int n, char chunk_bytes)
 
 	ucthread = calloc(sizeof(struct uncomp_thread), total_threads);
 	if (unlikely(!ucthread)) {
-		free(sinfo);
-		free(threads);
+		dealloc(sinfo);
+		dealloc(threads);
 		fatal_return(("Unable to calloc cthread in open_stream_in\n"), NULL);
 	}
 
@@ -1092,7 +1092,7 @@ void *open_stream_in(rzip_control *control, int f, int n, char chunk_bytes)
 
 	sinfo->s = calloc(sizeof(struct stream), n);
 	if (unlikely(!sinfo->s)) {
-		free(sinfo);
+		dealloc(sinfo);
 		return NULL;
 	}
 
@@ -1208,8 +1208,8 @@ void *open_stream_in(rzip_control *control, int f, int n, char chunk_bytes)
 	return (void *)sinfo;
 
 failed:
-	free(sinfo->s);
-	free(sinfo);
+	dealloc(sinfo->s);
+	dealloc(sinfo);
 	return NULL;
 }
 
@@ -1248,11 +1248,11 @@ static bool rewrite_encrypted(rzip_control *control, struct stream_info *sinfo,
 		failure_goto(("Failed to seek back to ofs in rewrite_encrypted\n"), error);
 	if (unlikely(write_buf(control, buf, 25)))
 		failure_goto(("Failed to write_buf encrypted buf in rewrite_encrypted\n"), error);
-	free(head);
+	dealloc(head);
 	seekto(control, sinfo, cur_ofs);
 	return true;
 error:
-	free(head);
+	dealloc(head);
 	return false;
 }
 
@@ -1271,7 +1271,7 @@ static void *compthread(void *data)
 
 	/* Make sure this thread doesn't already exist */
 
-	free(data);
+	dealloc(data);
 	cti = &cthread[i];
 	ctis = cti->sinfo;
 
@@ -1441,7 +1441,7 @@ static void *compthread(void *data)
 		fatal_goto(("Failed to write_buf s_buf in compthread %d\n", i), error);
 
 	ctis->cur_pos += padded_len;
-	free(cti->s_buf);
+	dealloc(cti->s_buf);
 
 	lock_mutex(control, &output_lock);
 	if (++output_thread == control->threads)
@@ -1509,7 +1509,7 @@ static void *ucompthread(void *data)
 	struct uncomp_thread *uci;
 	int waited = 0, ret = 0;
 
-	free(data);
+	dealloc(data);
 	uci = &ucthread[i];
 
 	if (unlikely(setpriority(PRIO_PROCESS, 0, control->nice_val) == -1))
@@ -1570,8 +1570,7 @@ static int fill_buffer(rzip_control *control, struct stream_info *sinfo, int str
 	stream_thread_struct *st;
 	uchar c_type, *s_buf;
 
-	if (s->buf)
-		free(s->buf);
+	dealloc(s->buf);
 	if (s->eos)
 		goto out;
 fill_another:
@@ -1671,7 +1670,7 @@ static int fill_buffer(rzip_control *control, struct stream_info *sinfo, int str
 	st->i = s->uthread_no;
 	st->control = control;
 	if (unlikely(!create_pthread(control, &threads[s->uthread_no], NULL, ucompthread, st))) {
-		free(st);
+		dealloc(st);
 		return -1;
 	}
 
@@ -1814,8 +1813,8 @@ int close_stream_out(rzip_control *control, void *ss)
 	 * stream has started. Instead (in library mode), they are stored and only freed
 	 * after the entire operation has completed.
 	 */
-	free(sinfo->s);
-	free(sinfo);
+	dealloc(sinfo->s);
+	dealloc(sinfo);
 #endif
 	return 0;
 }
@@ -1833,13 +1832,13 @@ int close_stream_in(rzip_control *control, void *ss)
 		return -1;
 
 	for (i = 0; i < sinfo->num_streams; i++)
-		free(sinfo->s[i].buf);
+		dealloc(sinfo->s[i].buf);
 
 	output_thread = 0;
-	free(ucthread);
-	free(threads);
-	free(sinfo->s);
-	free(sinfo);
+	dealloc(ucthread);
+	dealloc(threads);
+	dealloc(sinfo->s);
+	dealloc(sinfo);
 
 	return 0;
 }
@@ -1871,7 +1870,7 @@ static int lzo_compresses(rzip_control *control, uchar *s_buf, i64 s_len)
 
 	c_buf = malloc(dlen);
 	if (unlikely(!c_buf)) {
-		free(wrkmem);
+		dealloc(wrkmem);
 		fatal_return(("Unable to allocate c_buf in lzo_compresses\n"), 0);
 	}
 
@@ -1901,8 +1900,8 @@ static int lzo_compresses(rzip_control *control, uchar *s_buf, i64 s_len)
 			(ret == 0? "FAILED" : "OK"), save_len,
 			100 * ((double) best_dlen / (double) in_len), workcounter);
 
-	free(wrkmem);
-	free(c_buf);
+	dealloc(wrkmem);
+	dealloc(c_buf);
 
 	return ret;
 }