Blame SOURCES/0010-libsemanage-move-compressed-file-handling-into-a-sep.patch

83eaee
From f8c74eaf19df123deabe9e2c71bd5b3c2beba06a Mon Sep 17 00:00:00 2001
83eaee
From: Ondrej Mosnacek <omosnace@redhat.com>
83eaee
Date: Thu, 3 Feb 2022 17:53:24 +0100
83eaee
Subject: [PATCH] libsemanage: move compressed file handling into a separate
83eaee
 object
83eaee
83eaee
In order to reduce exisiting and future code duplication and to avoid
83eaee
some unnecessary allocations and copying, factor the compressed file
83eaee
utility functions out into a separate C/header file and refactor their
83eaee
interface.
83eaee
83eaee
Note that this change effectively removes the __fsetlocking(3) call from
83eaee
semanage_load_files() - I haven't been able to figure out what purpose
83eaee
it serves, but it seems pointless...
83eaee
83eaee
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
83eaee
---
83eaee
 libsemanage/src/compressed_file.c | 224 +++++++++++++++++++++++++
83eaee
 libsemanage/src/compressed_file.h |  78 +++++++++
83eaee
 libsemanage/src/direct_api.c      | 263 +++++-------------------------
83eaee
 libsemanage/src/direct_api.h      |   4 -
83eaee
 libsemanage/src/semanage_store.c  |  52 ++----
83eaee
 5 files changed, 354 insertions(+), 267 deletions(-)
83eaee
 create mode 100644 libsemanage/src/compressed_file.c
83eaee
 create mode 100644 libsemanage/src/compressed_file.h
83eaee
83eaee
diff --git a/libsemanage/src/compressed_file.c b/libsemanage/src/compressed_file.c
83eaee
new file mode 100644
83eaee
index 00000000..5546b830
83eaee
--- /dev/null
83eaee
+++ b/libsemanage/src/compressed_file.c
83eaee
@@ -0,0 +1,224 @@
83eaee
+/* Author: Jason Tang	  <jtang@tresys.com>
83eaee
+ *         Christopher Ashworth <cashworth@tresys.com>
83eaee
+ *         Ondrej Mosnacek <omosnacek@gmail.com>
83eaee
+ *
83eaee
+ * Copyright (C) 2004-2006 Tresys Technology, LLC
83eaee
+ * Copyright (C) 2005-2021 Red Hat, Inc.
83eaee
+ *
83eaee
+ *  This library is free software; you can redistribute it and/or
83eaee
+ *  modify it under the terms of the GNU Lesser General Public
83eaee
+ *  License as published by the Free Software Foundation; either
83eaee
+ *  version 2.1 of the License, or (at your option) any later version.
83eaee
+ *
83eaee
+ *  This library is distributed in the hope that it will be useful,
83eaee
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
83eaee
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
83eaee
+ *  Lesser General Public License for more details.
83eaee
+ *
83eaee
+ *  You should have received a copy of the GNU Lesser General Public
83eaee
+ *  License along with this library; if not, write to the Free Software
83eaee
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
83eaee
+ */
83eaee
+
83eaee
+#include <stdlib.h>
83eaee
+#include <string.h>
83eaee
+#include <stdint.h>
83eaee
+
83eaee
+#include <unistd.h>
83eaee
+#include <fcntl.h>
83eaee
+
83eaee
+#include <bzlib.h>
83eaee
+
83eaee
+#include "compressed_file.h"
83eaee
+
83eaee
+#include "debug.h"
83eaee
+
83eaee
+#define BZ2_MAGICSTR "BZh"
83eaee
+#define BZ2_MAGICLEN (sizeof(BZ2_MAGICSTR)-1)
83eaee
+
83eaee
+/* bzip() a data to a file, returning the total number of compressed bytes
83eaee
+ * in the file.  Returns -1 if file could not be compressed. */
83eaee
+static int bzip(semanage_handle_t *sh, const char *filename, void *data,
83eaee
+		size_t num_bytes)
83eaee
+{
83eaee
+	BZFILE* b;
83eaee
+	size_t  size = 1<<16;
83eaee
+	int     bzerror;
83eaee
+	size_t  total = 0;
83eaee
+	size_t len = 0;
83eaee
+	FILE *f;
83eaee
+
83eaee
+	if ((f = fopen(filename, "wb")) == NULL) {
83eaee
+		return -1;
83eaee
+	}
83eaee
+
83eaee
+	if (!sh->conf->bzip_blocksize) {
83eaee
+		if (fwrite(data, 1, num_bytes, f) < num_bytes) {
83eaee
+			fclose(f);
83eaee
+			return -1;
83eaee
+		}
83eaee
+		fclose(f);
83eaee
+		return 0;
83eaee
+	}
83eaee
+
83eaee
+	b = BZ2_bzWriteOpen( &bzerror, f, sh->conf->bzip_blocksize, 0, 0);
83eaee
+	if (bzerror != BZ_OK) {
83eaee
+		BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
83eaee
+		fclose(f);
83eaee
+		return -1;
83eaee
+	}
83eaee
+
83eaee
+	while ( num_bytes > total ) {
83eaee
+		if (num_bytes - total > size) {
83eaee
+			len = size;
83eaee
+		} else {
83eaee
+			len = num_bytes - total;
83eaee
+		}
83eaee
+		BZ2_bzWrite ( &bzerror, b, (uint8_t *)data + total, len );
83eaee
+		if (bzerror == BZ_IO_ERROR) {
83eaee
+			BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
83eaee
+			fclose(f);
83eaee
+			return -1;
83eaee
+		}
83eaee
+		total += len;
83eaee
+	}
83eaee
+
83eaee
+	BZ2_bzWriteClose ( &bzerror, b, 0, 0, 0 );
83eaee
+	fclose(f);
83eaee
+	if (bzerror == BZ_IO_ERROR) {
83eaee
+		return -1;
83eaee
+	}
83eaee
+	return 0;
83eaee
+}
83eaee
+
83eaee
+/* bunzip() a file to '*data', returning the total number of uncompressed bytes
83eaee
+ * in the file.  Returns -1 if file could not be decompressed. */
83eaee
+static ssize_t bunzip(semanage_handle_t *sh, FILE *f, void **data)
83eaee
+{
83eaee
+	BZFILE*  b = NULL;
83eaee
+	size_t   nBuf;
83eaee
+	uint8_t* buf = NULL;
83eaee
+	size_t   size = 1<<18;
83eaee
+	size_t   bufsize = size;
83eaee
+	int      bzerror;
83eaee
+	size_t   total = 0;
83eaee
+	uint8_t* uncompress = NULL;
83eaee
+	uint8_t* tmpalloc = NULL;
83eaee
+	int      ret = -1;
83eaee
+
83eaee
+	buf = malloc(bufsize);
83eaee
+	if (buf == NULL) {
83eaee
+		ERR(sh, "Failure allocating memory.");
83eaee
+		goto exit;
83eaee
+	}
83eaee
+
83eaee
+	/* Check if the file is bzipped */
83eaee
+	bzerror = fread(buf, 1, BZ2_MAGICLEN, f);
83eaee
+	rewind(f);
83eaee
+	if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) {
83eaee
+		goto exit;
83eaee
+	}
83eaee
+
83eaee
+	b = BZ2_bzReadOpen ( &bzerror, f, 0, sh->conf->bzip_small, NULL, 0 );
83eaee
+	if ( bzerror != BZ_OK ) {
83eaee
+		ERR(sh, "Failure opening bz2 archive.");
83eaee
+		goto exit;
83eaee
+	}
83eaee
+
83eaee
+	uncompress = malloc(size);
83eaee
+	if (uncompress == NULL) {
83eaee
+		ERR(sh, "Failure allocating memory.");
83eaee
+		goto exit;
83eaee
+	}
83eaee
+
83eaee
+	while ( bzerror == BZ_OK) {
83eaee
+		nBuf = BZ2_bzRead ( &bzerror, b, buf, bufsize);
83eaee
+		if (( bzerror == BZ_OK ) || ( bzerror == BZ_STREAM_END )) {
83eaee
+			if (total + nBuf > size) {
83eaee
+				size *= 2;
83eaee
+				tmpalloc = realloc(uncompress, size);
83eaee
+				if (tmpalloc == NULL) {
83eaee
+					ERR(sh, "Failure allocating memory.");
83eaee
+					goto exit;
83eaee
+				}
83eaee
+				uncompress = tmpalloc;
83eaee
+			}
83eaee
+			memcpy(&uncompress[total], buf, nBuf);
83eaee
+			total += nBuf;
83eaee
+		}
83eaee
+	}
83eaee
+	if ( bzerror != BZ_STREAM_END ) {
83eaee
+		ERR(sh, "Failure reading bz2 archive.");
83eaee
+		goto exit;
83eaee
+	}
83eaee
+
83eaee
+	ret = total;
83eaee
+	*data = uncompress;
83eaee
+
83eaee
+exit:
83eaee
+	BZ2_bzReadClose ( &bzerror, b );
83eaee
+	free(buf);
83eaee
+	if ( ret < 0 ) {
83eaee
+		free(uncompress);
83eaee
+	}
83eaee
+	return ret;
83eaee
+}
83eaee
+
83eaee
+int map_compressed_file(semanage_handle_t *sh, const char *path,
83eaee
+			struct file_contents *contents)
83eaee
+{
83eaee
+	ssize_t size = -1;
83eaee
+	void *uncompress;
83eaee
+	int ret = 0, fd = -1;
83eaee
+	FILE *file = NULL;
83eaee
+
83eaee
+	fd = open(path, O_RDONLY);
83eaee
+	if (fd == -1) {
83eaee
+		ERR(sh, "Unable to open %s\n", path);
83eaee
+		return -1;
83eaee
+	}
83eaee
+
83eaee
+	file = fdopen(fd, "r");
83eaee
+	if (file == NULL) {
83eaee
+		ERR(sh, "Unable to open %s\n", path);
83eaee
+		close(fd);
83eaee
+		return -1;
83eaee
+	}
83eaee
+
83eaee
+	if ((size = bunzip(sh, file, &uncompress)) >= 0) {
83eaee
+		contents->data = uncompress;
83eaee
+		contents->len = size;
83eaee
+		contents->compressed = 1;
83eaee
+	} else {
83eaee
+		struct stat sb;
83eaee
+		if (fstat(fd, &sb) == -1 ||
83eaee
+		    (uncompress = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) ==
83eaee
+		    MAP_FAILED) {
83eaee
+			ret = -1;
83eaee
+		} else {
83eaee
+			contents->data = uncompress;
83eaee
+			contents->len = sb.st_size;
83eaee
+			contents->compressed = 0;
83eaee
+		}
83eaee
+	}
83eaee
+	fclose(file);
83eaee
+	return ret;
83eaee
+}
83eaee
+
83eaee
+void unmap_compressed_file(struct file_contents *contents)
83eaee
+{
83eaee
+	if (!contents->data)
83eaee
+		return;
83eaee
+
83eaee
+	if (contents->compressed) {
83eaee
+		free(contents->data);
83eaee
+	} else {
83eaee
+		munmap(contents->data, contents->len);
83eaee
+	}
83eaee
+}
83eaee
+
83eaee
+int write_compressed_file(semanage_handle_t *sh, const char *path,
83eaee
+			  void *data, size_t len)
83eaee
+{
83eaee
+	return bzip(sh, path, data, len);
83eaee
+}
83eaee
diff --git a/libsemanage/src/compressed_file.h b/libsemanage/src/compressed_file.h
83eaee
new file mode 100644
83eaee
index 00000000..96cfb4b6
83eaee
--- /dev/null
83eaee
+++ b/libsemanage/src/compressed_file.h
83eaee
@@ -0,0 +1,78 @@
83eaee
+/* Author: Jason Tang	  <jtang@tresys.com>
83eaee
+ *         Christopher Ashworth <cashworth@tresys.com>
83eaee
+ *         Ondrej Mosnacek <omosnacek@gmail.com>
83eaee
+ *
83eaee
+ * Copyright (C) 2004-2006 Tresys Technology, LLC
83eaee
+ * Copyright (C) 2005-2021 Red Hat, Inc.
83eaee
+ *
83eaee
+ *  This library is free software; you can redistribute it and/or
83eaee
+ *  modify it under the terms of the GNU Lesser General Public
83eaee
+ *  License as published by the Free Software Foundation; either
83eaee
+ *  version 2.1 of the License, or (at your option) any later version.
83eaee
+ *
83eaee
+ *  This library is distributed in the hope that it will be useful,
83eaee
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
83eaee
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
83eaee
+ *  Lesser General Public License for more details.
83eaee
+ *
83eaee
+ *  You should have received a copy of the GNU Lesser General Public
83eaee
+ *  License along with this library; if not, write to the Free Software
83eaee
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
83eaee
+ */
83eaee
+
83eaee
+#ifndef _SEMANAGE_CIL_FILE_H_
83eaee
+#define _SEMANAGE_CIL_FILE_H_
83eaee
+
83eaee
+#include <sys/mman.h>
83eaee
+#include <sys/types.h>
83eaee
+
83eaee
+#include "handle.h"
83eaee
+
83eaee
+struct file_contents {
83eaee
+	void *data; /** file contents (uncompressed) */
83eaee
+	size_t len; /** length of contents */
83eaee
+	int compressed; /** whether file was compressed */
83eaee
+};
83eaee
+
83eaee
+/**
83eaee
+ * Map/read a possibly-compressed file into memory.
83eaee
+ *
83eaee
+ * If the file is bzip compressed map_file will uncompress the file into
83eaee
+ * @p contents. The caller is responsible for calling
83eaee
+ * @ref unmap_compressed_file on @p contents on success.
83eaee
+ *
83eaee
+ * @param sh        semanage handle
83eaee
+ * @param path      path to the file
83eaee
+ * @param contents  pointer to struct file_contents, which will be
83eaee
+ *   populated with data pointer, size, and an indication whether
83eaee
+ *   the file was compressed or not
83eaee
+ *
83eaee
+ * @return 0 on success, -1 otherwise.
83eaee
+ */
83eaee
+int map_compressed_file(semanage_handle_t *sh, const char *path,
83eaee
+			struct file_contents *contents);
83eaee
+
83eaee
+/**
83eaee
+ * Destroy a previously mapped possibly-compressed file.
83eaee
+ *
83eaee
+ * If all fields of @p contents are zero/NULL, the function is
83eaee
+ * guaranteed to do nothing.
83eaee
+ *
83eaee
+ * @param contents  pointer to struct file_contents to destroy
83eaee
+ */
83eaee
+void unmap_compressed_file(struct file_contents *contents);
83eaee
+
83eaee
+/**
83eaee
+ * Write bytes into a file, using compression if configured.
83eaee
+ *
83eaee
+ * @param sh    semanage handle
83eaee
+ * @param path  path to the file
83eaee
+ * @param data  pointer to the data
83eaee
+ * @param len   length of the data
83eaee
+ *
83eaee
+ * @return 0 on success, -1 otherwise.
83eaee
+ */
83eaee
+int write_compressed_file(semanage_handle_t *sh, const char *path,
83eaee
+			  void *data, size_t len);
83eaee
+
83eaee
+#endif
83eaee
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
83eaee
index 7638653a..63a18808 100644
83eaee
--- a/libsemanage/src/direct_api.c
83eaee
+++ b/libsemanage/src/direct_api.c
83eaee
@@ -50,6 +50,7 @@
83eaee
 
83eaee
 #include "debug.h"
83eaee
 #include "handle.h"
83eaee
+#include "compressed_file.h"
83eaee
 #include "modules.h"
83eaee
 #include "direct_api.h"
83eaee
 #include "semanage_store.h"
83eaee
@@ -446,194 +447,6 @@ static int parse_module_headers(semanage_handle_t * sh, char *module_data,
83eaee
        return 0;
83eaee
 }
83eaee
 
83eaee
-#include <stdlib.h>
83eaee
-#include <bzlib.h>
83eaee
-#include <string.h>
83eaee
-#include <sys/sendfile.h>
83eaee
-
83eaee
-/* bzip() a data to a file, returning the total number of compressed bytes
83eaee
- * in the file.  Returns -1 if file could not be compressed. */
83eaee
-static ssize_t bzip(semanage_handle_t *sh, const char *filename, char *data,
83eaee
-			size_t num_bytes)
83eaee
-{
83eaee
-	BZFILE* b;
83eaee
-	size_t  size = 1<<16;
83eaee
-	int     bzerror;
83eaee
-	size_t  total = 0;
83eaee
-	size_t len = 0;
83eaee
-	FILE *f;
83eaee
-
83eaee
-	if ((f = fopen(filename, "wb")) == NULL) {
83eaee
-		return -1;
83eaee
-	}
83eaee
-
83eaee
-	if (!sh->conf->bzip_blocksize) {
83eaee
-		if (fwrite(data, 1, num_bytes, f) < num_bytes) {
83eaee
-			fclose(f);
83eaee
-			return -1;
83eaee
-		}
83eaee
-		fclose(f);
83eaee
-		return num_bytes;
83eaee
-	}
83eaee
-
83eaee
-	b = BZ2_bzWriteOpen( &bzerror, f, sh->conf->bzip_blocksize, 0, 0);
83eaee
-	if (bzerror != BZ_OK) {
83eaee
-		BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
83eaee
-		return -1;
83eaee
-	}
83eaee
-	
83eaee
-	while ( num_bytes > total ) {
83eaee
-		if (num_bytes - total > size) {
83eaee
-			len = size;
83eaee
-		} else {
83eaee
-			len = num_bytes - total;
83eaee
-		}
83eaee
-		BZ2_bzWrite ( &bzerror, b, &data[total], len );
83eaee
-		if (bzerror == BZ_IO_ERROR) { 
83eaee
-			BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
83eaee
-			return -1;
83eaee
-		}
83eaee
-		total += len;
83eaee
-	}
83eaee
-
83eaee
-	BZ2_bzWriteClose ( &bzerror, b, 0, 0, 0 );
83eaee
-	fclose(f);
83eaee
-	if (bzerror == BZ_IO_ERROR) {
83eaee
-		return -1;
83eaee
-	}
83eaee
-	return total;
83eaee
-}
83eaee
-
83eaee
-#define BZ2_MAGICSTR "BZh"
83eaee
-#define BZ2_MAGICLEN (sizeof(BZ2_MAGICSTR)-1)
83eaee
-
83eaee
-/* bunzip() a file to '*data', returning the total number of uncompressed bytes
83eaee
- * in the file.  Returns -1 if file could not be decompressed. */
83eaee
-ssize_t bunzip(semanage_handle_t *sh, FILE *f, char **data)
83eaee
-{
83eaee
-	BZFILE* b = NULL;
83eaee
-	size_t  nBuf;
83eaee
-	char*   buf = NULL;
83eaee
-	size_t  size = 1<<18;
83eaee
-	size_t  bufsize = size;
83eaee
-	int     bzerror;
83eaee
-	size_t  total = 0;
83eaee
-	char*   uncompress = NULL;
83eaee
-	char*   tmpalloc = NULL;
83eaee
-	int     ret = -1;
83eaee
-
83eaee
-	buf = malloc(bufsize);
83eaee
-	if (buf == NULL) {
83eaee
-		ERR(sh, "Failure allocating memory.");
83eaee
-		goto exit;
83eaee
-	}
83eaee
-
83eaee
-	/* Check if the file is bzipped */
83eaee
-	bzerror = fread(buf, 1, BZ2_MAGICLEN, f);
83eaee
-	rewind(f);
83eaee
-	if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) {
83eaee
-		goto exit;
83eaee
-	}
83eaee
-
83eaee
-	b = BZ2_bzReadOpen ( &bzerror, f, 0, sh->conf->bzip_small, NULL, 0 );
83eaee
-	if ( bzerror != BZ_OK ) {
83eaee
-		ERR(sh, "Failure opening bz2 archive.");
83eaee
-		goto exit;
83eaee
-	}
83eaee
-
83eaee
-	uncompress = malloc(size);
83eaee
-	if (uncompress == NULL) {
83eaee
-		ERR(sh, "Failure allocating memory.");
83eaee
-		goto exit;
83eaee
-	}
83eaee
-
83eaee
-	while ( bzerror == BZ_OK) {
83eaee
-		nBuf = BZ2_bzRead ( &bzerror, b, buf, bufsize);
83eaee
-		if (( bzerror == BZ_OK ) || ( bzerror == BZ_STREAM_END )) {
83eaee
-			if (total + nBuf > size) {
83eaee
-				size *= 2;
83eaee
-				tmpalloc = realloc(uncompress, size);
83eaee
-				if (tmpalloc == NULL) {
83eaee
-					ERR(sh, "Failure allocating memory.");
83eaee
-					goto exit;
83eaee
-				}
83eaee
-				uncompress = tmpalloc;
83eaee
-			}
83eaee
-			memcpy(&uncompress[total], buf, nBuf);
83eaee
-			total += nBuf;
83eaee
-		}
83eaee
-	}
83eaee
-	if ( bzerror != BZ_STREAM_END ) {
83eaee
-		ERR(sh, "Failure reading bz2 archive.");
83eaee
-		goto exit;
83eaee
-	}
83eaee
-
83eaee
-	ret = total;
83eaee
-	*data = uncompress;
83eaee
-
83eaee
-exit:
83eaee
-	BZ2_bzReadClose ( &bzerror, b );
83eaee
-	free(buf);
83eaee
-	if ( ret < 0 ) {
83eaee
-		free(uncompress);
83eaee
-	}
83eaee
-	return ret;
83eaee
-}
83eaee
-
83eaee
-/* mmap() a file to '*data',
83eaee
- *  If the file is bzip compressed map_file will uncompress 
83eaee
- * the file into '*data'.
83eaee
- * Returns the total number of bytes in memory .
83eaee
- * Returns -1 if file could not be opened or mapped. */
83eaee
-static ssize_t map_file(semanage_handle_t *sh, const char *path, char **data,
83eaee
-			int *compressed)
83eaee
-{
83eaee
-	ssize_t size = -1;
83eaee
-	char *uncompress;
83eaee
-	int fd = -1;
83eaee
-	FILE *file = NULL;
83eaee
-
83eaee
-	fd = open(path, O_RDONLY);
83eaee
-	if (fd == -1) {
83eaee
-		ERR(sh, "Unable to open %s\n", path);
83eaee
-		return -1;
83eaee
-	}
83eaee
-
83eaee
-	file = fdopen(fd, "r");
83eaee
-	if (file == NULL) {
83eaee
-		ERR(sh, "Unable to open %s\n", path);
83eaee
-		close(fd);
83eaee
-		return -1;
83eaee
-	}
83eaee
-
83eaee
-	if ((size = bunzip(sh, file, &uncompress)) > 0) {
83eaee
-		*data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
83eaee
-		if (*data == MAP_FAILED) {
83eaee
-			free(uncompress);
83eaee
-			fclose(file);
83eaee
-			return -1;
83eaee
-		} else {
83eaee
-			memcpy(*data, uncompress, size);
83eaee
-		}
83eaee
-		free(uncompress);
83eaee
-		*compressed = 1;
83eaee
-	} else {
83eaee
-		struct stat sb;
83eaee
-		if (fstat(fd, &sb) == -1 ||
83eaee
-		    (*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) ==
83eaee
-		    MAP_FAILED) {
83eaee
-			size = -1;
83eaee
-		} else {
83eaee
-			size = sb.st_size;
83eaee
-		}
83eaee
-		*compressed = 0;
83eaee
-	} 
83eaee
-
83eaee
-	fclose(file);
83eaee
-
83eaee
-	return size;
83eaee
-}
83eaee
-
83eaee
 /* Writes a block of data to a file.  Returns 0 on success, -1 on
83eaee
  * error. */
83eaee
 static int write_file(semanage_handle_t * sh,
83eaee
@@ -1045,15 +858,12 @@ static int semanage_compile_module(semanage_handle_t *sh,
83eaee
 	char *compiler_path = NULL;
83eaee
 	char *cil_data = NULL;
83eaee
 	char *err_data = NULL;
83eaee
-	char *hll_data = NULL;
83eaee
 	char *start = NULL;
83eaee
 	char *end = NULL;
83eaee
-	ssize_t hll_data_len = 0;
83eaee
-	ssize_t bzip_status;
83eaee
 	int status = 0;
83eaee
-	int compressed;
83eaee
 	size_t cil_data_len = 0;
83eaee
 	size_t err_data_len = 0;
83eaee
+	struct file_contents hll_contents = {};
83eaee
 
83eaee
 	if (!strcasecmp(modinfo->lang_ext, "cil")) {
83eaee
 		goto cleanup;
83eaee
@@ -1084,13 +894,15 @@ static int semanage_compile_module(semanage_handle_t *sh,
83eaee
 		goto cleanup;
83eaee
 	}
83eaee
 
83eaee
-	if ((hll_data_len = map_file(sh, hll_path, &hll_data, &compressed)) <= 0) {
83eaee
+	status = map_compressed_file(sh, hll_path, &hll_contents);
83eaee
+	if (status < 0) {
83eaee
 		ERR(sh, "Unable to read file %s\n", hll_path);
83eaee
-		status = -1;
83eaee
 		goto cleanup;
83eaee
 	}
83eaee
 
83eaee
-	status = semanage_pipe_data(sh, compiler_path, hll_data, (size_t)hll_data_len, &cil_data, &cil_data_len, &err_data, &err_data_len);
83eaee
+	status = semanage_pipe_data(sh, compiler_path, hll_contents.data,
83eaee
+				    hll_contents.len, &cil_data, &cil_data_len,
83eaee
+				    &err_data, &err_data_len);
83eaee
 	if (err_data_len > 0) {
83eaee
 		for (start = end = err_data; end < err_data + err_data_len; end++) {
83eaee
 			if (*end == '\n') {
83eaee
@@ -1110,10 +922,9 @@ static int semanage_compile_module(semanage_handle_t *sh,
83eaee
 		goto cleanup;
83eaee
 	}
83eaee
 
83eaee
-	bzip_status = bzip(sh, cil_path, cil_data, cil_data_len);
83eaee
-	if (bzip_status == -1) {
83eaee
-		ERR(sh, "Failed to bzip %s\n", cil_path);
83eaee
-		status = -1;
83eaee
+	status = write_compressed_file(sh, cil_path, cil_data, cil_data_len);
83eaee
+	if (status == -1) {
83eaee
+		ERR(sh, "Failed to write %s\n", cil_path);
83eaee
 		goto cleanup;
83eaee
 	}
83eaee
 
83eaee
@@ -1131,9 +942,7 @@ static int semanage_compile_module(semanage_handle_t *sh,
83eaee
 	}
83eaee
 
83eaee
 cleanup:
83eaee
-	if (hll_data_len > 0) {
83eaee
-		munmap(hll_data, hll_data_len);
83eaee
-	}
83eaee
+	unmap_compressed_file(&hll_contents);
83eaee
 	free(cil_data);
83eaee
 	free(err_data);
83eaee
 	free(compiler_path);
83eaee
@@ -1749,19 +1558,17 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
83eaee
 {
83eaee
 
83eaee
 	int retval = -1;
83eaee
-	char *data = NULL;
83eaee
-	ssize_t data_len = 0;
83eaee
-	int compressed = 0;
83eaee
 	char *path = NULL;
83eaee
 	char *filename;
83eaee
 	char *lang_ext = NULL;
83eaee
 	char *module_name = NULL;
83eaee
 	char *separator;
83eaee
 	char *version = NULL;
83eaee
+	struct file_contents contents = {};
83eaee
 
83eaee
-	if ((data_len = map_file(sh, install_filename, &data, &compressed)) <= 0) {
83eaee
+	retval = map_compressed_file(sh, install_filename, &contents);
83eaee
+	if (retval < 0) {
83eaee
 		ERR(sh, "Unable to read file %s\n", install_filename);
83eaee
-		retval = -1;
83eaee
 		goto cleanup;
83eaee
 	}
83eaee
 
83eaee
@@ -1774,7 +1581,7 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
83eaee
 
83eaee
 	filename = basename(path);
83eaee
 
83eaee
-	if (compressed) {
83eaee
+	if (contents.compressed) {
83eaee
 		separator = strrchr(filename, '.');
83eaee
 		if (separator == NULL) {
83eaee
 			ERR(sh, "Compressed module does not have a valid extension.");
83eaee
@@ -1798,7 +1605,8 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
83eaee
 	}
83eaee
 
83eaee
 	if (strcmp(lang_ext, "pp") == 0) {
83eaee
-		retval = parse_module_headers(sh, data, data_len, &module_name, &version);
83eaee
+		retval = parse_module_headers(sh, contents.data, contents.len,
83eaee
+					      &module_name, &version);
83eaee
 		free(version);
83eaee
 		if (retval != 0)
83eaee
 			goto cleanup;
83eaee
@@ -1815,10 +1623,11 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
83eaee
 		fprintf(stderr, "Warning: SELinux userspace will refer to the module from %s as %s rather than %s\n", install_filename, module_name, filename);
83eaee
 	}
83eaee
 
83eaee
-	retval = semanage_direct_install(sh, data, data_len, module_name, lang_ext);
83eaee
+	retval = semanage_direct_install(sh, contents.data, contents.len,
83eaee
+					 module_name, lang_ext);
83eaee
 
83eaee
 cleanup:
83eaee
-	if (data_len > 0) munmap(data, data_len);
83eaee
+	unmap_compressed_file(&contents);
83eaee
 	free(module_name);
83eaee
 	free(path);
83eaee
 
83eaee
@@ -1837,10 +1646,8 @@ static int semanage_direct_extract(semanage_handle_t * sh,
83eaee
 	enum semanage_module_path_type file_type;
83eaee
 	int rc = -1;
83eaee
 	semanage_module_info_t *_modinfo = NULL;
83eaee
-	ssize_t _data_len;
83eaee
-	char *_data;
83eaee
-	int compressed;
83eaee
 	struct stat sb;
83eaee
+	struct file_contents contents = {};
83eaee
 
83eaee
 	/* get path of module */
83eaee
 	rc = semanage_module_get_path(
83eaee
@@ -1896,19 +1703,33 @@ static int semanage_direct_extract(semanage_handle_t * sh,
83eaee
 		}
83eaee
 	}
83eaee
 
83eaee
-	_data_len = map_file(sh, input_file, &_data, &compressed);
83eaee
-	if (_data_len <= 0) {
83eaee
+	rc = map_compressed_file(sh, input_file, &contents);
83eaee
+	if (rc < 0) {
83eaee
 		ERR(sh, "Error mapping file: %s", input_file);
83eaee
-		rc = -1;
83eaee
 		goto cleanup;
83eaee
 	}
83eaee
 
83eaee
+	/* The API promises an mmap'ed pointer */
83eaee
+	if (contents.compressed) {
83eaee
+		*mapped_data = mmap(NULL, contents.len, PROT_READ|PROT_WRITE,
83eaee
+				    MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
83eaee
+		if (*mapped_data == MAP_FAILED) {
83eaee
+			ERR(sh, "Unable to map memory");
83eaee
+			rc = -1;
83eaee
+			goto cleanup;
83eaee
+		}
83eaee
+		memcpy(*mapped_data, contents.data, contents.len);
83eaee
+		free(contents.data);
83eaee
+	} else {
83eaee
+		*mapped_data = contents.data;
83eaee
+	}
83eaee
+
83eaee
 	*modinfo = _modinfo;
83eaee
-	*data_len = (size_t)_data_len;
83eaee
-	*mapped_data = _data;
83eaee
+	*data_len = contents.len;
83eaee
 
83eaee
 cleanup:
83eaee
 	if (rc != 0) {
83eaee
+		unmap_compressed_file(&contents);
83eaee
 		semanage_module_info_destroy(sh, _modinfo);
83eaee
 		free(_modinfo);
83eaee
 	}
83eaee
@@ -2857,8 +2678,8 @@ static int semanage_direct_install_info(semanage_handle_t *sh,
83eaee
 		goto cleanup;
83eaee
 	}
83eaee
 
83eaee
-	ret = bzip(sh, path, data, data_len);
83eaee
-	if (ret <= 0) {
83eaee
+	ret = write_compressed_file(sh, path, data, data_len);
83eaee
+	if (ret < 0) {
83eaee
 		ERR(sh, "Error while writing to %s.", path);
83eaee
 		status = -3;
83eaee
 		goto cleanup;
83eaee
diff --git a/libsemanage/src/direct_api.h b/libsemanage/src/direct_api.h
83eaee
index e56107b2..ffd428eb 100644
83eaee
--- a/libsemanage/src/direct_api.h
83eaee
+++ b/libsemanage/src/direct_api.h
83eaee
@@ -39,8 +39,4 @@ int semanage_direct_access_check(struct semanage_handle *sh);
83eaee
 
83eaee
 int semanage_direct_mls_enabled(struct semanage_handle *sh);
83eaee
 
83eaee
-#include <stdio.h>
83eaee
-#include <unistd.h>
83eaee
-ssize_t bunzip(struct semanage_handle *sh, FILE *f, char **data);
83eaee
-
83eaee
 #endif
83eaee
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
83eaee
index ae023582..c5ce071c 100644
83eaee
--- a/libsemanage/src/semanage_store.c
83eaee
+++ b/libsemanage/src/semanage_store.c
83eaee
@@ -59,6 +59,7 @@ typedef struct dbase_policydb dbase_t;
83eaee
 
83eaee
 #include "debug.h"
83eaee
 #include "utilities.h"
83eaee
+#include "compressed_file.h"
83eaee
 
83eaee
 #define SEMANAGE_CONF_FILE "semanage.conf"
83eaee
 /* relative path names to enum semanage_paths to special files and
83eaee
@@ -2055,60 +2056,27 @@ int semanage_direct_get_serial(semanage_handle_t * sh)
83eaee
 
83eaee
 int semanage_load_files(semanage_handle_t * sh, cil_db_t *cildb, char **filenames, int numfiles)
83eaee
 {
83eaee
-	int retval = 0;
83eaee
-	FILE *fp;
83eaee
-	ssize_t size;
83eaee
-	char *data = NULL;
83eaee
+	int i, retval = 0;
83eaee
 	char *filename;
83eaee
-	int i;
83eaee
+	struct file_contents contents = {};
83eaee
 
83eaee
 	for (i = 0; i < numfiles; i++) {
83eaee
 		filename = filenames[i];
83eaee
 
83eaee
-		if ((fp = fopen(filename, "rb")) == NULL) {
83eaee
-			ERR(sh, "Could not open module file %s for reading.", filename);
83eaee
-			goto cleanup;
83eaee
-		}
83eaee
-
83eaee
-		if ((size = bunzip(sh, fp, &data)) <= 0) {
83eaee
-			rewind(fp);
83eaee
-			__fsetlocking(fp, FSETLOCKING_BYCALLER);
83eaee
-
83eaee
-			if (fseek(fp, 0, SEEK_END) != 0) {
83eaee
-				ERR(sh, "Failed to determine size of file %s.", filename);
83eaee
-				goto cleanup;
83eaee
-			}
83eaee
-			size = ftell(fp);
83eaee
-			rewind(fp);
83eaee
-
83eaee
-			data = malloc(size);
83eaee
-			if (fread(data, size, 1, fp) != 1) {
83eaee
-				ERR(sh, "Failed to read file %s.", filename);
83eaee
-				goto cleanup;
83eaee
-			}
83eaee
-		}
83eaee
+		retval = map_compressed_file(sh, filename, &contents);
83eaee
+		if (retval < 0)
83eaee
+			return -1;
83eaee
 
83eaee
-		fclose(fp);
83eaee
-		fp = NULL;
83eaee
+		retval = cil_add_file(cildb, filename, contents.data, contents.len);
83eaee
+		unmap_compressed_file(&contents);
83eaee
 
83eaee
-		retval = cil_add_file(cildb, filename, data, size);
83eaee
 		if (retval != SEPOL_OK) {
83eaee
 			ERR(sh, "Error while reading from file %s.", filename);
83eaee
-			goto cleanup;
83eaee
+			return -1;
83eaee
 		}
83eaee
-	
83eaee
-		free(data);
83eaee
-		data = NULL;
83eaee
 	}
83eaee
 
83eaee
-	return retval;
83eaee
-
83eaee
-      cleanup:
83eaee
-	if (fp != NULL) {
83eaee
-		fclose(fp);
83eaee
-	}
83eaee
-	free(data);
83eaee
-	return -1;
83eaee
+	return 0;
83eaee
 }
83eaee
 
83eaee
 /* 
83eaee
-- 
83eaee
2.30.2
83eaee