Re: [RFC PATCH userspace 3/5] libsemanage: move compressed file handling into a separate object

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Jan 13, 2022 at 6:36 PM Ondrej Mosnacek <omosnace@xxxxxxxxxx> wrote:
>
> In order to reduce exisiting and future code duplication and to avoid
> some unnecessary allocations and copying, factor the compressed file
> utility functions out into a separate C/header file and refactor their
> interface.
>
> Note that this change effectively removes the __fsetlocking(3) call from
> semanage_load_files() - I haven't been able to figure out what purpose
> it serves, but it seems pointless...
>

I don't know what purpose it had either.
Jim


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



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux