diff -purN libsemanage-2.0.33.orig/src/conf-parse.y libsemanage-2.0.33/src/conf-parse.y --- libsemanage-2.0.33.orig/src/conf-parse.y 2009-07-30 22:14:16.000000000 -0400 +++ libsemanage-2.0.33/src/conf-parse.y 2009-08-24 14:17:59.255304232 -0400 @@ -58,6 +58,7 @@ static int parse_errors; %token MODULE_STORE VERSION EXPAND_CHECK FILE_MODE SAVE_PREVIOUS SAVE_LINKED %token LOAD_POLICY_START SETFILES_START DISABLE_GENHOMEDIRCON HANDLE_UNKNOWN +%token BZIP_BLOCKSIZE BZIP_SMALL %token VERIFY_MOD_START VERIFY_LINKED_START VERIFY_KERNEL_START BLOCK_END %token PROG_PATH PROG_ARGS %token ARG @@ -82,6 +83,8 @@ single_opt: module_store | save_linked | disable_genhomedircon | handle_unknown + | bzip_blocksize + | bzip_small ; module_store: MODULE_STORE '=' ARG { @@ -163,6 +166,26 @@ handle_unknown: HANDLE_UNKNOWN '=' ARG { free($3); } +bzip_blocksize: BZIP_BLOCKSIZE '=' ARG { + int blocksize = atoi($3); + free($3); + if (blocksize > 9) + yyerror("bzip-blocksize can only be in the range 0-9"); + else + current_conf->bzip_blocksize = blocksize; +} + +bzip_small: BZIP_SMALL '=' ARG { + if (strcasecmp($3, "false") == 0) { + current_conf->bzip_small = 0; + } else if (strcasecmp($3, "true") == 0) { + current_conf->bzip_small = 1; + } else { + yyerror("bzip-small can only be 'true' or 'false'"); + } + free($3); +} + command_block: command_start external_opts BLOCK_END { if (new_external->path == NULL) { @@ -230,6 +253,8 @@ static int semanage_conf_init(semanage_c conf->expand_check = 1; conf->handle_unknown = -1; conf->file_mode = 0644; + conf->bzip_blocksize = 9; + conf->bzip_small = 0; conf->save_previous = 0; conf->save_linked = 0; diff -purN libsemanage-2.0.33.orig/src/conf-scan.l libsemanage-2.0.33/src/conf-scan.l --- libsemanage-2.0.33.orig/src/conf-scan.l 2009-07-30 22:14:16.000000000 -0400 +++ libsemanage-2.0.33/src/conf-scan.l 2009-08-24 14:17:59.255304232 -0400 @@ -47,6 +47,8 @@ save-previous return SAVE_PREVIOUS; save-linked return SAVE_LINKED; disable-genhomedircon return DISABLE_GENHOMEDIRCON; handle-unknown return HANDLE_UNKNOWN; +bzip-blocksize return BZIP_BLOCKSIZE; +bzip-small return BZIP_SMALL; "[load_policy]" return LOAD_POLICY_START; "[setfiles]" return SETFILES_START; "[verify module]" return VERIFY_MOD_START; diff -purN libsemanage-2.0.33.orig/src/direct_api.c libsemanage-2.0.33/src/direct_api.c --- libsemanage-2.0.33.orig/src/direct_api.c 2009-07-30 22:14:16.000000000 -0400 +++ libsemanage-2.0.33/src/direct_api.c 2009-08-24 14:18:16.895213296 -0400 @@ -401,7 +401,9 @@ static int parse_base_headers(semanage_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(const char *filename, char *data, size_t num_bytes) { +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; @@ -413,7 +415,16 @@ static ssize_t bzip(const char *filename return -1; } - b = BZ2_bzWriteOpen( &bzerror, f, 9, 0, 0); + 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; @@ -441,17 +452,29 @@ static ssize_t bzip(const char *filename 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(FILE *f, char **data) { +ssize_t bunzip(semanage_handle_t *sh, FILE *f, char **data) +{ BZFILE* b; size_t nBuf; char buf[1<<18]; size_t size = sizeof(buf); int bzerror; size_t total=0; + + if (!sh->conf->bzip_blocksize) { + bzerror = fread(buf, 1, BZ2_MAGICLEN, f); + rewind(f); + if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) + return -1; + /* fall through */ + } - b = BZ2_bzReadOpen ( &bzerror, f, 0, 0, NULL, 0 ); + b = BZ2_bzReadOpen ( &bzerror, f, 0, sh->conf->bzip_small, NULL, 0 ); if ( bzerror != BZ_OK ) { BZ2_bzReadClose ( &bzerror, b ); return -1; @@ -486,11 +509,12 @@ ssize_t bunzip(FILE *f, char **data) { * 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(int fd, char **data, int *compressed) +static ssize_t map_file(semanage_handle_t *sh, int fd, char **data, + int *compressed) { ssize_t size = -1; char *uncompress; - if ((size = bunzip(fdopen(fd, "r"), &uncompress)) > 0) { + if ((size = bunzip(sh, fdopen(fd, "r"), &uncompress)) > 0) { *data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); if (*data == MAP_FAILED) { free(uncompress); @@ -997,7 +1021,7 @@ static int semanage_direct_install(seman &filename)) != 0) { goto cleanup; } - if (bzip(filename, data, data_len) <= 0) { + if (bzip(sh, filename, data, data_len) <= 0) { ERR(sh, "Error while writing to %s.", filename); retval = -3; goto cleanup; @@ -1029,7 +1053,7 @@ static int semanage_direct_install_file( return -1; } - if ((data_len = map_file(in_fd, &data, &compressed)) <= 0) { + if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) { goto cleanup; } @@ -1127,7 +1151,7 @@ static int semanage_direct_upgrade(seman data, data_len, &filename); if (retval == 0) { - if (bzip(filename, data, data_len) <= 0) { + if (bzip(sh, filename, data, data_len) <= 0) { ERR(sh, "Error while writing to %s.", filename); retval = -3; } @@ -1155,7 +1179,7 @@ static int semanage_direct_upgrade_file( return -1; } - if ((data_len = map_file(in_fd, &data, &compressed)) <= 0) { + if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) { goto cleanup; } @@ -1197,7 +1221,7 @@ static int semanage_direct_install_base( if ((filename = semanage_path(SEMANAGE_TMP, SEMANAGE_BASE)) == NULL) { goto cleanup; } - if (bzip(filename, base_data, data_len) <= 0) { + if (bzip(sh, filename, base_data, data_len) <= 0) { ERR(sh, "Error while writing to %s.", filename); retval = -3; goto cleanup; @@ -1225,7 +1249,7 @@ static int semanage_direct_install_base_ return -1; } - if ((data_len = map_file(in_fd, &data, &compressed)) <= 0) { + if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) { goto cleanup; } @@ -1347,7 +1371,7 @@ static int semanage_direct_list(semanage ssize_t size; char *data = NULL; - if ((size = bunzip(fp, &data)) > 0) { + if ((size = bunzip(sh, fp, &data)) > 0) { fclose(fp); fp = fmemopen(data, size, "rb"); if (!fp) { diff -purN libsemanage-2.0.33.orig/src/direct_api.h libsemanage-2.0.33/src/direct_api.h --- libsemanage-2.0.33.orig/src/direct_api.h 2009-07-30 22:14:16.000000000 -0400 +++ libsemanage-2.0.33/src/direct_api.h 2009-08-24 14:17:59.271293736 -0400 @@ -41,6 +41,6 @@ int semanage_direct_mls_enabled(struct s #include #include -ssize_t bunzip(FILE *f, char **data); +ssize_t bunzip(struct semanage_handle *sh, FILE *f, char **data); #endif diff -purN libsemanage-2.0.33.orig/src/semanage_conf.h libsemanage-2.0.33/src/semanage_conf.h --- libsemanage-2.0.33.orig/src/semanage_conf.h 2009-07-30 22:14:16.000000000 -0400 +++ libsemanage-2.0.33/src/semanage_conf.h 2009-08-24 14:17:59.279293237 -0400 @@ -40,6 +40,8 @@ typedef struct semanage_conf { int disable_genhomedircon; int handle_unknown; mode_t file_mode; + int bzip_blocksize; + int bzip_small; struct external_prog *load_policy; struct external_prog *setfiles; struct external_prog *mod_prog, *linked_prog, *kernel_prog; diff -purN libsemanage-2.0.33.orig/src/semanage_store.c libsemanage-2.0.33/src/semanage_store.c --- libsemanage-2.0.33.orig/src/semanage_store.c 2009-07-30 22:14:16.000000000 -0400 +++ libsemanage-2.0.33/src/semanage_store.c 2009-08-24 14:17:59.283234006 -0400 @@ -1529,7 +1529,7 @@ static int semanage_load_module(semanage ssize_t size; char *data = NULL; - if ((size = bunzip(fp, &data)) > 0) { + if ((size = bunzip(sh, fp, &data)) > 0) { fclose(fp); fp = fmemopen(data, size, "rb"); if (!fp) {