From 4d223ca33ed26499fc0fe7e383a107277a11ba31 Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Tue, 13 Mar 2018 12:58:59 +0100 Subject: [PATCH] libsemanage-2.7-10 * Tue Mar 13 2018 Petr Lautrbach - 2.7-10 - properly check return value of iterate function - Use umask(0077) for fopen() write operations - Return commit number if save-previous false - Allow tmp files to be kept if a compile fails - build: follow standard semantics for DESTDIR and PREFIX - Improve warning for installing disabled module - silence clang static analyzer report - remove access() check to make setuid programs work --- libsemanage-fedora.patch | 786 +++++++++++++++++++++++++++++++++++++-- libsemanage.spec | 23 +- 2 files changed, 777 insertions(+), 32 deletions(-) diff --git a/libsemanage-fedora.patch b/libsemanage-fedora.patch index ac014b5..7d7ab4a 100644 --- a/libsemanage-fedora.patch +++ b/libsemanage-fedora.patch @@ -1,3 +1,23 @@ +diff --git libsemanage-2.7/include/Makefile libsemanage-2.7/include/Makefile +index b660660..6e44a28 100644 +--- libsemanage-2.7/include/Makefile ++++ libsemanage-2.7/include/Makefile +@@ -1,12 +1,12 @@ + # Installation directories. +-PREFIX ?= $(DESTDIR)/usr ++PREFIX ?= /usr + INCDIR ?= $(PREFIX)/include/semanage + + all: + + install: all +- test -d $(INCDIR) || install -m 755 -d $(INCDIR) +- install -m 644 $(wildcard semanage/*.h) $(INCDIR) ++ test -d $(DESTDIR)$(INCDIR) || install -m 755 -d $(DESTDIR)$(INCDIR) ++ install -m 644 $(wildcard semanage/*.h) $(DESTDIR)$(INCDIR) + + indent: + ../../scripts/Lindent $(wildcard semanage/*.h) diff --git libsemanage-2.7/include/semanage/fcontexts_policy.h libsemanage-2.7/include/semanage/fcontexts_policy.h index a50db2b..199a1e1 100644 --- libsemanage-2.7/include/semanage/fcontexts_policy.h @@ -11,11 +31,156 @@ index a50db2b..199a1e1 100644 + unsigned int *count); + #endif +diff --git libsemanage-2.7/man/Makefile libsemanage-2.7/man/Makefile +index 852043d..8667c9b 100644 +--- libsemanage-2.7/man/Makefile ++++ libsemanage-2.7/man/Makefile +@@ -1,12 +1,13 @@ + # Installation directories. +-MAN3DIR ?= $(DESTDIR)/usr/share/man/man3 +-MAN5DIR ?= $(DESTDIR)/usr/share/man/man5 ++PREFIX ?= /usr ++MAN3DIR ?= $(PREFIX)/share/man/man3 ++MAN5DIR ?= $(PREFIX)/share/man/man5 + + all: + + install: all +- mkdir -p $(MAN3DIR) +- mkdir -p $(MAN5DIR) +- install -m 644 man3/*.3 $(MAN3DIR) +- install -m 644 man5/*.5 $(MAN5DIR) ++ mkdir -p $(DESTDIR)$(MAN3DIR) ++ mkdir -p $(DESTDIR)$(MAN5DIR) ++ install -m 644 man3/*.3 $(DESTDIR)$(MAN3DIR) ++ install -m 644 man5/*.5 $(DESTDIR)$(MAN5DIR) + +diff --git libsemanage-2.7/src/Makefile libsemanage-2.7/src/Makefile +index fdb178f..e98d876 100644 +--- libsemanage-2.7/src/Makefile ++++ libsemanage-2.7/src/Makefile +@@ -8,21 +8,18 @@ RUBYPREFIX ?= $(notdir $(RUBY)) + PKG_CONFIG ?= pkg-config + + # Installation directories. +-PREFIX ?= $(DESTDIR)/usr ++PREFIX ?= /usr + LIBDIR ?= $(PREFIX)/lib +-SHLIBDIR ?= $(DESTDIR)/lib + INCLUDEDIR ?= $(PREFIX)/include + PYINC ?= $(shell $(PKG_CONFIG) --cflags $(PYPREFIX)) + PYLIBS ?= $(shell $(PKG_CONFIG) --libs $(PYPREFIX)) +-PYSITEDIR ?= $(DESTDIR)$(shell $(PYTHON) -c 'import site; print(site.getsitepackages()[0])') ++PYSITEDIR ?= $(shell $(PYTHON) -c 'import site; print(site.getsitepackages()[0])') + PYCEXT ?= $(shell $(PYTHON) -c 'import imp;print([s for s,m,t in imp.get_suffixes() if t == imp.C_EXTENSION][0])') + RUBYINC ?= $(shell $(RUBY) -e 'puts "-I" + RbConfig::CONFIG["rubyarchhdrdir"] + " -I" + RbConfig::CONFIG["rubyhdrdir"]') + RUBYLIBS ?= $(shell $(RUBY) -e 'puts "-L" + RbConfig::CONFIG["libdir"] + " -L" + RbConfig::CONFIG["archlibdir"] + " " + RbConfig::CONFIG["LIBRUBYARG_SHARED"]') +-RUBYINSTALL ?= $(DESTDIR)$(shell $(RUBY) -e 'puts RbConfig::CONFIG["vendorarchdir"]') ++RUBYINSTALL ?= $(shell $(RUBY) -e 'puts RbConfig::CONFIG["vendorarchdir"]') + +-LIBBASE=$(shell basename $(LIBDIR)) +- +-DEFAULT_SEMANAGE_CONF_LOCATION=$(DESTDIR)/etc/selinux/semanage.conf ++DEFAULT_SEMANAGE_CONF_LOCATION=/etc/selinux/semanage.conf + + ifeq ($(DEBUG),1) + export CFLAGS = -g3 -O0 -gdwarf-2 -fno-strict-aliasing -Wall -Wshadow -Werror +@@ -95,7 +92,7 @@ $(LIBSO): $(LOBJS) + ln -sf $@ $(TARGET) + + $(LIBPC): $(LIBPC).in ../VERSION +- sed -e 's/@VERSION@/$(VERSION)/; s:@prefix@:$(PREFIX):; s:@libdir@:$(LIBBASE):; s:@includedir@:$(INCLUDEDIR):' < $< > $@ ++ sed -e 's/@VERSION@/$(VERSION)/; s:@prefix@:$(PREFIX):; s:@libdir@:$(LIBDIR):; s:@includedir@:$(INCLUDEDIR):' < $< > $@ + + semanageswig_python_exception.i: ../include/semanage/semanage.h + bash -e exception.sh > $@ || (rm -f $@ ; false) +@@ -136,26 +133,26 @@ swigify: $(SWIGIF) + $(SWIG) $< + + install: all +- test -d $(LIBDIR) || install -m 755 -d $(LIBDIR) +- install -m 644 $(LIBA) $(LIBDIR) +- install -m 755 $(LIBSO) $(LIBDIR) +- test -d $(LIBDIR)/pkgconfig || install -m 755 -d $(LIBDIR)/pkgconfig +- install -m 644 $(LIBPC) $(LIBDIR)/pkgconfig +- test -f $(DEFAULT_SEMANAGE_CONF_LOCATION) || install -m 644 -D semanage.conf $(DEFAULT_SEMANAGE_CONF_LOCATION) +- cd $(LIBDIR) && ln -sf $(LIBSO) $(TARGET) ++ test -d $(DESTDIR)$(LIBDIR) || install -m 755 -d $(DESTDIR)$(LIBDIR) ++ install -m 644 $(LIBA) $(DESTDIR)$(LIBDIR) ++ install -m 755 $(LIBSO) $(DESTDIR)$(LIBDIR) ++ test -d $(DESTDIR)$(LIBDIR)/pkgconfig || install -m 755 -d $(DESTDIR)$(LIBDIR)/pkgconfig ++ install -m 644 $(LIBPC) $(DESTDIR)$(LIBDIR)/pkgconfig ++ test -f $(DESTDIR)$(DEFAULT_SEMANAGE_CONF_LOCATION) || install -m 644 -D semanage.conf $(DESTDIR)$(DEFAULT_SEMANAGE_CONF_LOCATION) ++ cd $(DESTDIR)$(LIBDIR) && ln -sf $(LIBSO) $(TARGET) + + install-pywrap: pywrap +- test -d $(PYSITEDIR) || install -m 755 -d $(PYSITEDIR) +- install -m 755 $(SWIGSO) $(PYSITEDIR)/_semanage$(PYCEXT) +- install -m 644 semanage.py $(PYSITEDIR) ++ test -d $(DESTDIR)$(PYSITEDIR) || install -m 755 -d $(DESTDIR)$(PYSITEDIR) ++ install -m 755 $(SWIGSO) $(DESTDIR)$(PYSITEDIR)/_semanage$(PYCEXT) ++ install -m 644 semanage.py $(DESTDIR)$(PYSITEDIR) + + + install-rubywrap: rubywrap +- test -d $(RUBYINSTALL) || install -m 755 -d $(RUBYINSTALL) +- install -m 755 $(SWIGRUBYSO) $(RUBYINSTALL)/semanage.so ++ test -d $(DESTDIR)$(RUBYINSTALL) || install -m 755 -d $(DESTDIR)$(RUBYINSTALL) ++ install -m 755 $(SWIGRUBYSO) $(DESTDIR)$(RUBYINSTALL)/semanage.so + + relabel: +- /sbin/restorecon $(LIBDIR)/$(LIBSO) ++ /sbin/restorecon $(DESTDIR)$(LIBDIR)/$(LIBSO) + + clean: + -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(SWIGRUBYSO) $(TARGET) conf-parse.c conf-parse.h conf-scan.c *.o *.lo *~ +diff --git libsemanage-2.7/src/database_file.c libsemanage-2.7/src/database_file.c +index a21b3ee..a51269e 100644 +--- libsemanage-2.7/src/database_file.c ++++ libsemanage-2.7/src/database_file.c +@@ -119,13 +119,16 @@ static int dbase_file_flush(semanage_handle_t * handle, dbase_file_t * dbase) + cache_entry_t *ptr; + const char *fname = NULL; + FILE *str = NULL; ++ mode_t mask; + + if (!dbase_llist_is_modified(&dbase->llist)) + return STATUS_SUCCESS; + + fname = dbase->path[handle->is_in_transaction]; + ++ mask = umask(0077); + str = fopen(fname, "w"); ++ umask(mask); + if (!str) { + ERR(handle, "could not open %s for writing: %s", + fname, strerror(errno)); +diff --git libsemanage-2.7/src/database_llist.c libsemanage-2.7/src/database_llist.c +index 8ce2e2c..c8f4ff0 100644 +--- libsemanage-2.7/src/database_llist.c ++++ libsemanage-2.7/src/database_llist.c +@@ -263,7 +263,7 @@ int dbase_llist_iterate(semanage_handle_t * handle, + if (rc < 0) + goto err; + +- else if (rc > 1) ++ else if (rc > 0) + break; + } + diff --git libsemanage-2.7/src/direct_api.c libsemanage-2.7/src/direct_api.c -index 65842df..31fcada 100644 +index 65842df..439122d 100644 --- libsemanage-2.7/src/direct_api.c +++ libsemanage-2.7/src/direct_api.c -@@ -148,9 +148,6 @@ int semanage_direct_connect(semanage_handle_t * sh) +@@ -140,6 +140,7 @@ int semanage_direct_is_managed(semanage_handle_t * sh) + int semanage_direct_connect(semanage_handle_t * sh) + { + const char *path; ++ struct stat sb; + + if (semanage_check_init(sh, sh->conf->store_root_path)) + goto err; +@@ -148,9 +149,6 @@ int semanage_direct_connect(semanage_handle_t * sh) if (semanage_create_store(sh, 1)) goto err; @@ -25,7 +190,7 @@ index 65842df..31fcada 100644 sh->u.direct.translock_file_fd = -1; sh->u.direct.activelock_file_fd = -1; -@@ -210,6 +207,12 @@ int semanage_direct_connect(semanage_handle_t * sh) +@@ -210,6 +208,12 @@ int semanage_direct_connect(semanage_handle_t * sh) semanage_fcontext_dbase_local(sh)) < 0) goto err; @@ -38,7 +203,79 @@ index 65842df..31fcada 100644 if (seuser_file_dbase_init(sh, semanage_path(SEMANAGE_ACTIVE, SEMANAGE_SEUSERS_LOCAL), -@@ -349,6 +352,7 @@ static int semanage_direct_disconnect(semanage_handle_t * sh) +@@ -299,10 +303,16 @@ int semanage_direct_connect(semanage_handle_t * sh) + + /* set the disable dontaudit value */ + path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_DISABLE_DONTAUDIT); +- if (access(path, F_OK) == 0) ++ ++ if (stat(path, &sb) == 0) + sepol_set_disable_dontaudit(sh->sepolh, 1); +- else ++ else if (errno == ENOENT) { ++ /* The file does not exist */ + sepol_set_disable_dontaudit(sh->sepolh, 0); ++ } else { ++ ERR(sh, "Unable to access %s: %s\n", path, strerror(errno)); ++ goto err; ++ } + + return STATUS_SUCCESS; + +@@ -317,25 +327,43 @@ static void semanage_direct_destroy(semanage_handle_t * sh + /* do nothing */ + } + +-static int semanage_direct_disconnect(semanage_handle_t * sh) ++static int semanage_remove_tmps(semanage_handle_t *sh) + { +- /* destroy transaction */ +- if (sh->is_in_transaction) { +- /* destroy sandbox */ +- if (semanage_remove_directory +- (semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)) < 0) { ++ if (sh->commit_err) ++ return 0; ++ ++ /* destroy sandbox if it exists */ ++ if (semanage_remove_directory ++ (semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)) < 0) { ++ if (errno != ENOENT) { + ERR(sh, "Could not cleanly remove sandbox %s.", + semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)); + return -1; + } +- if (semanage_remove_directory +- (semanage_final_path(SEMANAGE_FINAL_TMP, +- SEMANAGE_FINAL_TOPLEVEL)) < 0) { ++ } ++ ++ /* destroy tmp policy if it exists */ ++ if (semanage_remove_directory ++ (semanage_final_path(SEMANAGE_FINAL_TMP, ++ SEMANAGE_FINAL_TOPLEVEL)) < 0) { ++ if (errno != ENOENT) { + ERR(sh, "Could not cleanly remove tmp %s.", + semanage_final_path(SEMANAGE_FINAL_TMP, + SEMANAGE_FINAL_TOPLEVEL)); + return -1; + } ++ } ++ ++ return 0; ++} ++ ++static int semanage_direct_disconnect(semanage_handle_t *sh) ++{ ++ int retval = 0; ++ ++ /* destroy transaction and remove tmp files if no commit error */ ++ if (sh->is_in_transaction) { ++ retval = semanage_remove_tmps(sh); + semanage_release_trans_lock(sh); + } + +@@ -349,6 +377,7 @@ static int semanage_direct_disconnect(semanage_handle_t * sh) iface_file_dbase_release(semanage_iface_dbase_local(sh)); bool_file_dbase_release(semanage_bool_dbase_local(sh)); fcontext_file_dbase_release(semanage_fcontext_dbase_local(sh)); @@ -46,7 +283,13 @@ index 65842df..31fcada 100644 seuser_file_dbase_release(semanage_seuser_dbase_local(sh)); node_file_dbase_release(semanage_node_dbase_local(sh)); -@@ -373,10 +377,6 @@ static int semanage_direct_disconnect(semanage_handle_t * sh) +@@ -368,15 +397,11 @@ static int semanage_direct_disconnect(semanage_handle_t * sh) + /* Release object databases: active kernel policy */ + bool_activedb_dbase_release(semanage_bool_dbase_active(sh)); + +- return 0; ++ return retval; + } static int semanage_direct_begintrans(semanage_handle_t * sh) { @@ -57,10 +300,200 @@ index 65842df..31fcada 100644 if (semanage_get_trans_lock(sh) < 0) { return -1; } -@@ -1545,43 +1545,46 @@ rebuild: +@@ -1121,6 +1146,7 @@ static int semanage_compile_hll_modules(semanage_handle_t *sh, + int status = 0; + int i; + char cil_path[PATH_MAX]; ++ struct stat sb; + + assert(sh); + assert(modinfos); +@@ -1137,9 +1163,13 @@ static int semanage_compile_hll_modules(semanage_handle_t *sh, + } + + if (semanage_get_ignore_module_cache(sh) == 0 && +- access(cil_path, F_OK) == 0) { ++ (status = stat(cil_path, &sb)) == 0) { + continue; + } ++ if (status != 0 && errno != ENOENT) { ++ ERR(sh, "Unable to access %s: %s\n", cil_path, strerror(errno)); ++ goto cleanup; //an error in the "stat" call ++ } + + status = semanage_compile_module(sh, &modinfos[i]); + if (status < 0) { +@@ -1153,6 +1183,14 @@ cleanup: + return status; + } + ++/* Copies a file from src to dst. If dst already exists then ++ * overwrite it. If source doesn't exist then return success. ++ * Returns 0 on success, -1 on error. */ ++static int copy_file_if_exists(const char *src, const char *dst, mode_t mode){ ++ int rc = semanage_copy_file(src, dst, mode); ++ return (rc < 0 && errno != ENOENT) ? rc : 0; ++} ++ + /********************* direct API functions ********************/ + + /* Commits all changes in sandbox to the actual kernel policy. +@@ -1169,6 +1207,8 @@ static int semanage_direct_commit(semanage_handle_t * sh) + sepol_policydb_t *out = NULL; + struct cil_db *cildb = NULL; + semanage_module_info_t *modinfos = NULL; ++ mode_t mask = umask(0077); ++ struct stat sb; + + int do_rebuild, do_write_kernel, do_install; + int fcontexts_modified, ports_modified, seusers_modified, +@@ -1207,10 +1247,16 @@ static int semanage_direct_commit(semanage_handle_t * sh) + + /* Create or remove the disable_dontaudit flag file. */ + path = semanage_path(SEMANAGE_TMP, SEMANAGE_DISABLE_DONTAUDIT); +- if (access(path, F_OK) == 0) ++ if (stat(path, &sb) == 0) + do_rebuild |= !(sepol_get_disable_dontaudit(sh->sepolh) == 1); +- else ++ else if (errno == ENOENT) { ++ /* The file does not exist */ + do_rebuild |= (sepol_get_disable_dontaudit(sh->sepolh) == 1); ++ } else { ++ ERR(sh, "Unable to access %s: %s\n", path, strerror(errno)); ++ retval = -1; ++ goto cleanup; ++ } + if (sepol_get_disable_dontaudit(sh->sepolh) == 1) { + FILE *touch; + touch = fopen(path, "w"); +@@ -1232,10 +1278,17 @@ static int semanage_direct_commit(semanage_handle_t * sh) + + /* Create or remove the preserve_tunables flag file. */ + path = semanage_path(SEMANAGE_TMP, SEMANAGE_PRESERVE_TUNABLES); +- if (access(path, F_OK) == 0) ++ if (stat(path, &sb) == 0) + do_rebuild |= !(sepol_get_preserve_tunables(sh->sepolh) == 1); +- else ++ else if (errno == ENOENT) { ++ /* The file does not exist */ + do_rebuild |= (sepol_get_preserve_tunables(sh->sepolh) == 1); ++ } else { ++ ERR(sh, "Unable to access %s: %s\n", path, strerror(errno)); ++ retval = -1; ++ goto cleanup; ++ } ++ + if (sepol_get_preserve_tunables(sh->sepolh) == 1) { + FILE *touch; + touch = fopen(path, "w"); +@@ -1272,40 +1325,25 @@ static int semanage_direct_commit(semanage_handle_t * sh) + * a rebuild. + */ + if (!do_rebuild) { +- path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL); +- if (access(path, F_OK) != 0) { +- do_rebuild = 1; +- goto rebuild; +- } +- +- path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC); +- if (access(path, F_OK) != 0) { +- do_rebuild = 1; +- goto rebuild; +- } +- +- path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS); +- if (access(path, F_OK) != 0) { +- do_rebuild = 1; +- goto rebuild; +- } +- +- path = semanage_path(SEMANAGE_TMP, SEMANAGE_LINKED); +- if (access(path, F_OK) != 0) { +- do_rebuild = 1; +- goto rebuild; +- } +- +- path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED); +- if (access(path, F_OK) != 0) { +- do_rebuild = 1; +- goto rebuild; +- } ++ int files[] = {SEMANAGE_STORE_KERNEL, ++ SEMANAGE_STORE_FC, ++ SEMANAGE_STORE_SEUSERS, ++ SEMANAGE_LINKED, ++ SEMANAGE_SEUSERS_LINKED, ++ SEMANAGE_USERS_EXTRA_LINKED}; ++ ++ for (i = 0; i < (int) sizeof(files); i++) { ++ path = semanage_path(SEMANAGE_TMP, files[i]); ++ if (stat(path, &sb) != 0) { ++ if (errno != ENOENT) { ++ ERR(sh, "Unable to access %s: %s\n", path, strerror(errno)); ++ retval = -1; ++ goto cleanup; ++ } + +- path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED); +- if (access(path, F_OK) != 0) { +- do_rebuild = 1; +- goto rebuild; ++ do_rebuild = 1; ++ goto rebuild; ++ } + } } - path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL); +@@ -1438,7 +1476,7 @@ rebuild: + goto cleanup; + + path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED); +- if (access(path, F_OK) == 0) { ++ if (stat(path, &sb) == 0) { + retval = semanage_copy_file(path, + semanage_path(SEMANAGE_TMP, + SEMANAGE_STORE_SEUSERS), +@@ -1446,12 +1484,17 @@ rebuild: + if (retval < 0) + goto cleanup; + pseusers->dtable->drop_cache(pseusers->dbase); +- } else { ++ } else if (errno == ENOENT) { ++ /* The file does not exist */ + pseusers->dtable->clear(sh, pseusers->dbase); ++ } else { ++ ERR(sh, "Unable to access %s: %s\n", path, strerror(errno)); ++ retval = -1; ++ goto cleanup; + } + + path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED); +- if (access(path, F_OK) == 0) { ++ if (stat(path, &sb) == 0) { + retval = semanage_copy_file(path, + semanage_path(SEMANAGE_TMP, + SEMANAGE_USERS_EXTRA), +@@ -1459,8 +1502,13 @@ rebuild: + if (retval < 0) + goto cleanup; + pusers_extra->dtable->drop_cache(pusers_extra->dbase); +- } else { ++ } else if (errno == ENOENT) { ++ /* The file does not exist */ + pusers_extra->dtable->clear(sh, pusers_extra->dbase); ++ } else { ++ ERR(sh, "Unable to access %s: %s\n", path, strerror(errno)); ++ retval = -1; ++ goto cleanup; + } + } + +@@ -1544,44 +1592,44 @@ rebuild: + goto cleanup; + } + +- path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL); - if (access(path, F_OK) == 0) { - retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL), - semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL), @@ -68,14 +501,14 @@ index 65842df..31fcada 100644 - if (retval < 0) { - goto cleanup; - } -+ retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL), ++ retval = copy_file_if_exists(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL), + semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL), + sh->conf->file_mode); -+ if (retval < 0 && errno != ENOENT) { ++ if (retval < 0) { + goto cleanup; } - path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC); +- path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC); - if (access(path, F_OK) == 0) { - retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC), - semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC), @@ -83,14 +516,14 @@ index 65842df..31fcada 100644 - if (retval < 0) { - goto cleanup; - } -+ retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC), ++ retval = copy_file_if_exists(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC), + semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC), + sh->conf->file_mode); -+ if (retval < 0 && errno != ENOENT) { ++ if (retval < 0) { + goto cleanup; } - path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS); +- path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS); - if (access(path, F_OK) == 0) { - retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS), - semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS), @@ -98,10 +531,10 @@ index 65842df..31fcada 100644 - if (retval < 0) { - goto cleanup; - } -+ retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS), ++ retval = copy_file_if_exists(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS), + semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS), + sh->conf->file_mode); -+ if (retval < 0 && errno != ENOENT) { ++ if (retval < 0) { + goto cleanup; } @@ -130,6 +563,151 @@ index 65842df..31fcada 100644 } } else { WARN(sh, "WARNING: genhomedircon is disabled. \ +@@ -1618,17 +1666,21 @@ cleanup: + free(mod_filenames); + sepol_policydb_free(out); + cil_db_destroy(&cildb); +- semanage_release_trans_lock(sh); + + free(fc_buffer); + +- /* regardless if the commit was successful or not, remove the +- sandbox if it is still there */ +- semanage_remove_directory(semanage_path +- (SEMANAGE_TMP, SEMANAGE_TOPLEVEL)); +- semanage_remove_directory(semanage_final_path +- (SEMANAGE_FINAL_TMP, +- SEMANAGE_FINAL_TOPLEVEL)); ++ /* Set commit_err so other functions can detect any errors. Note that ++ * retval > 0 will be the commit number. ++ */ ++ if (retval < 0) ++ sh->commit_err = retval; ++ ++ if (semanage_remove_tmps(sh) != 0) ++ retval = -1; ++ ++ semanage_release_trans_lock(sh); ++ umask(mask); ++ + return retval; + } + +@@ -1786,6 +1838,7 @@ static int semanage_direct_extract(semanage_handle_t * sh, + ssize_t _data_len; + char *_data; + int compressed; ++ struct stat sb; + + /* get path of module */ + rc = semanage_module_get_path( +@@ -1798,8 +1851,8 @@ static int semanage_direct_extract(semanage_handle_t * sh, + goto cleanup; + } + +- if (access(module_path, F_OK) != 0) { +- ERR(sh, "Module does not exist: %s", module_path); ++ if (stat(module_path, &sb) != 0) { ++ ERR(sh, "Unable to access %s: %s\n", module_path, strerror(errno)); + rc = -1; + goto cleanup; + } +@@ -1828,7 +1881,13 @@ static int semanage_direct_extract(semanage_handle_t * sh, + goto cleanup; + } + +- if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && access(input_file, F_OK) != 0) { ++ if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && stat(input_file, &sb) != 0) { ++ if (errno != ENOENT) { ++ ERR(sh, "Unable to access %s: %s\n", input_file, strerror(errno)); ++ rc = -1; ++ goto cleanup; ++ } ++ + rc = semanage_compile_module(sh, _modinfo); + if (rc < 0) { + goto cleanup; +@@ -1973,6 +2032,12 @@ static int semanage_direct_get_enabled(semanage_handle_t *sh, + } + + if (stat(path, &sb) < 0) { ++ if (errno != ENOENT) { ++ ERR(sh, "Unable to access %s: %s\n", path, strerror(errno)); ++ status = -1; ++ goto cleanup; ++ } ++ + *enabled = 1; + } + else { +@@ -2000,6 +2065,7 @@ static int semanage_direct_set_enabled(semanage_handle_t *sh, + const char *path = NULL; + FILE *fp = NULL; + semanage_module_info_t *modinfo = NULL; ++ mode_t mask; + + /* check transaction */ + if (!sh->is_in_transaction) { +@@ -2060,7 +2126,9 @@ static int semanage_direct_set_enabled(semanage_handle_t *sh, + + switch (enabled) { + case 0: /* disable the module */ ++ mask = umask(0077); + fp = fopen(fn, "w"); ++ umask(mask); + + if (fp == NULL) { + ERR(sh, +@@ -2296,6 +2364,12 @@ static int semanage_direct_get_module_info(semanage_handle_t *sh, + + /* set enabled/disabled status */ + if (stat(fn, &sb) < 0) { ++ if (errno != ENOENT) { ++ ERR(sh, "Unable to access %s: %s\n", fn, strerror(errno)); ++ status = -1; ++ goto cleanup; ++ } ++ + ret = semanage_module_info_set_enabled(sh, *modinfo, 1); + if (ret != 0) { + status = -1; +@@ -2704,8 +2778,10 @@ static int semanage_direct_install_info(semanage_handle_t *sh, + int status = 0; + int ret = 0; + int type; ++ struct stat sb; + + char path[PATH_MAX]; ++ mode_t mask = umask(0077); + + semanage_module_info_t *higher_info = NULL; + semanage_module_key_t higher_key; +@@ -2754,7 +2830,7 @@ static int semanage_direct_install_info(semanage_handle_t *sh, + if (higher_info->enabled == 0 && modinfo->enabled == -1) { + errno = 0; + WARN(sh, +- "%s module will be disabled after install due to default enabled status.", ++ "%s module will be disabled after install as there is a disabled instance of this module present in the system.", + modinfo->name); + } + } +@@ -2803,7 +2879,7 @@ static int semanage_direct_install_info(semanage_handle_t *sh, + goto cleanup; + } + +- if (access(path, F_OK) == 0) { ++ if (stat(path, &sb) == 0) { + ret = unlink(path); + if (ret != 0) { + ERR(sh, "Error while removing cached CIL file %s: %s", path, strerror(errno)); +@@ -2817,6 +2893,7 @@ cleanup: + semanage_module_key_destroy(sh, &higher_key); + semanage_module_info_destroy(sh, higher_info); + free(higher_info); ++ umask(mask); + + return status; + } diff --git libsemanage-2.7/src/fcontexts_policy.c libsemanage-2.7/src/fcontexts_policy.c index 0b063b1..98490ab 100644 --- libsemanage-2.7/src/fcontexts_policy.c @@ -172,11 +750,35 @@ index b9a74b7..d09d82f 100644 ignore_free(); return retval; +diff --git libsemanage-2.7/src/handle.c libsemanage-2.7/src/handle.c +index 4ce1df0..a6567bd 100644 +--- libsemanage-2.7/src/handle.c ++++ libsemanage-2.7/src/handle.c +@@ -86,6 +86,8 @@ semanage_handle_t *semanage_handle_create(void) + * If any changes are made, this flag is ignored */ + sh->do_rebuild = 0; + ++ sh->commit_err = 0; ++ + /* By default always reload policy after commit if SELinux is enabled. */ + sh->do_reload = (is_selinux_enabled() > 0); + diff --git libsemanage-2.7/src/handle.h libsemanage-2.7/src/handle.h -index 889871d..1780ac8 100644 +index 889871d..a91907b 100644 --- libsemanage-2.7/src/handle.h +++ libsemanage-2.7/src/handle.h -@@ -79,7 +79,7 @@ struct semanage_handle { +@@ -62,6 +62,10 @@ struct semanage_handle { + int is_in_transaction; + int do_reload; /* whether to reload policy after commit */ + int do_rebuild; /* whether to rebuild policy if there were no changes */ ++ int commit_err; /* set by semanage_direct_commit() if there are ++ * any errors when building or committing the ++ * sandbox to kernel policy at /etc/selinux ++ */ + int modules_modified; + int create_store; /* whether to create the store if it does not exist + * this will only have an effect on direct connections */ +@@ -79,7 +83,7 @@ struct semanage_handle { struct semanage_policy_table *funcs; /* Object databases */ @@ -185,7 +787,7 @@ index 889871d..1780ac8 100644 /* Local modifications */ #define DBASE_LOCAL_USERS_BASE 0 -@@ -102,13 +102,14 @@ struct semanage_handle { +@@ -102,13 +106,14 @@ struct semanage_handle { #define DBASE_POLICY_INTERFACES 15 #define DBASE_POLICY_BOOLEANS 16 #define DBASE_POLICY_FCONTEXTS 17 @@ -205,7 +807,7 @@ index 889871d..1780ac8 100644 dbase_config_t dbase[DBASE_COUNT]; }; -@@ -235,6 +236,12 @@ static inline +@@ -235,6 +240,12 @@ static inline return &handle->dbase[DBASE_POLICY_FCONTEXTS]; } @@ -218,8 +820,20 @@ index 889871d..1780ac8 100644 static inline dbase_config_t * semanage_seuser_dbase_policy(semanage_handle_t * handle) { +diff --git libsemanage-2.7/src/libsemanage.pc.in libsemanage-2.7/src/libsemanage.pc.in +index d3eaa06..43681dd 100644 +--- libsemanage-2.7/src/libsemanage.pc.in ++++ libsemanage-2.7/src/libsemanage.pc.in +@@ -1,6 +1,6 @@ + prefix=@prefix@ + exec_prefix=${prefix} +-libdir=${exec_prefix}/@libdir@ ++libdir=@libdir@ + includedir=@includedir@ + + Name: libsemanage diff --git libsemanage-2.7/src/semanage_store.c libsemanage-2.7/src/semanage_store.c -index 6158d08..320fa7b 100644 +index 6158d08..14ad99c 100644 --- libsemanage-2.7/src/semanage_store.c +++ libsemanage-2.7/src/semanage_store.c @@ -116,6 +116,7 @@ static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = { @@ -230,7 +844,24 @@ index 6158d08..320fa7b 100644 "/file_contexts", "/seusers" }; -@@ -537,7 +538,6 @@ char *semanage_conf_path(void) +@@ -513,6 +514,7 @@ char *semanage_conf_path(void) + { + char *semanage_conf = NULL; + int len; ++ struct stat sb; + + len = strlen(semanage_root()) + strlen(selinux_path()) + strlen(SEMANAGE_CONF_FILE); + semanage_conf = calloc(len + 1, sizeof(char)); +@@ -521,7 +523,7 @@ char *semanage_conf_path(void) + snprintf(semanage_conf, len + 1, "%s%s%s", semanage_root(), selinux_path(), + SEMANAGE_CONF_FILE); + +- if (access(semanage_conf, R_OK) != 0) { ++ if (stat(semanage_conf, &sb) != 0 && errno == ENOENT) { + snprintf(semanage_conf, len + 1, "%s%s", selinux_path(), SEMANAGE_CONF_FILE); + } + +@@ -537,7 +539,6 @@ char *semanage_conf_path(void) int semanage_create_store(semanage_handle_t * sh, int create) { struct stat sb; @@ -238,7 +869,7 @@ index 6158d08..320fa7b 100644 const char *path = semanage_files[SEMANAGE_ROOT]; int fd; -@@ -556,9 +556,9 @@ int semanage_create_store(semanage_handle_t * sh, int create) +@@ -556,9 +557,9 @@ int semanage_create_store(semanage_handle_t * sh, int create) return -1; } } else { @@ -250,7 +881,7 @@ index 6158d08..320fa7b 100644 path); return -1; } -@@ -579,9 +579,9 @@ int semanage_create_store(semanage_handle_t * sh, int create) +@@ -579,9 +580,9 @@ int semanage_create_store(semanage_handle_t * sh, int create) return -1; } } else { @@ -262,7 +893,7 @@ index 6158d08..320fa7b 100644 path); return -1; } -@@ -602,9 +602,9 @@ int semanage_create_store(semanage_handle_t * sh, int create) +@@ -602,9 +603,9 @@ int semanage_create_store(semanage_handle_t * sh, int create) return -1; } } else { @@ -274,17 +905,61 @@ index 6158d08..320fa7b 100644 path); return -1; } -@@ -623,8 +623,8 @@ int semanage_create_store(semanage_handle_t * sh, int create) +@@ -623,8 +624,8 @@ int semanage_create_store(semanage_handle_t * sh, int create) return -1; } } else { - if (!S_ISREG(sb.st_mode) || access(path, R_OK | W_OK) == -1) { - ERR(sh, "Could not access lock file at %s.", path); + if (!S_ISREG(sb.st_mode)) { -+ ERR(sh, "Lock file at %s missing.", path); ++ ERR(sh, "Object at %s is not a lock file.", path); return -1; } } +@@ -1508,8 +1509,14 @@ int semanage_split_fc(semanage_handle_t * sh) + static int sefcontext_compile(semanage_handle_t * sh, const char *path) { + + int r; ++ struct stat sb; ++ ++ if (stat(path, &sb) < 0) { ++ if (errno != ENOENT) { ++ ERR(sh, "Unable to access %s: %s\n", path, strerror(errno)); ++ return -1; ++ } + +- if (access(path, F_OK) != 0) { + return 0; + } + +@@ -1739,9 +1746,9 @@ static int semanage_commit_sandbox(semanage_handle_t * sh) + + if (!sh->conf->save_previous) { + int errsv = errno; +- retval = semanage_remove_directory(backup); +- if (retval < 0) { ++ if (semanage_remove_directory(backup) != 0) { + ERR(sh, "Could not delete previous directory %s.", backup); ++ retval = -1; + goto cleanup; + } + errno = errsv; +@@ -2098,6 +2105,7 @@ int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out, + const char *kernel_filename = NULL; + struct sepol_policy_file *pf = NULL; + FILE *outfile = NULL; ++ mode_t mask = umask(0077); + + if ((kernel_filename = + semanage_path(SEMANAGE_TMP, file)) == NULL) { +@@ -2126,6 +2134,7 @@ int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out, + if (outfile != NULL) { + fclose(outfile); + } ++ umask(mask); + sepol_policy_file_free(pf); + return retval; + } diff --git libsemanage-2.7/src/semanage_store.h libsemanage-2.7/src/semanage_store.h index fcaa505..34bf852 100644 --- libsemanage-2.7/src/semanage_store.h @@ -297,3 +972,62 @@ index fcaa505..34bf852 100644 SEMANAGE_STORE_FC, SEMANAGE_STORE_SEUSERS, SEMANAGE_STORE_NUM_PATHS +diff --git libsemanage-2.7/src/seusers_local.c libsemanage-2.7/src/seusers_local.c +index 42c3a8b..413ebdd 100644 +--- libsemanage-2.7/src/seusers_local.c ++++ libsemanage-2.7/src/seusers_local.c +@@ -35,12 +35,16 @@ static char *semanage_user_roles(semanage_handle_t * handle, const char *sename) + for (i = 0; i= %{libselinuxver} %description Security-enhanced Linux is a feature of the Linux® kernel and a number @@ -121,7 +122,7 @@ InstallPythonWrapper() { make \ PYTHON=$BinaryName \ - DESTDIR="${RPM_BUILD_ROOT}" LIBDIR="${RPM_BUILD_ROOT}%{_libdir}" SHLIBDIR="${RPM_BUILD_ROOT}/%{_libdir}" \ + DESTDIR="${RPM_BUILD_ROOT}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" \ install-pywrap } @@ -129,7 +130,7 @@ mkdir -p ${RPM_BUILD_ROOT}%{_libdir} mkdir -p ${RPM_BUILD_ROOT}%{_includedir} mkdir -p ${RPM_BUILD_ROOT}%{_sharedstatedir}/selinux mkdir -p ${RPM_BUILD_ROOT}%{_sharedstatedir}/selinux/tmp -make DESTDIR="${RPM_BUILD_ROOT}" LIBDIR="${RPM_BUILD_ROOT}%{_libdir}" SHLIBDIR="${RPM_BUILD_ROOT}/%{_libdir}" install +make DESTDIR="${RPM_BUILD_ROOT}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install InstallPythonWrapper \ %{__python} \ @@ -178,6 +179,16 @@ sed -i '1s%\(#! */usr/bin/python\)\([^3].*\|\)$%\13\2%' %{buildroot}%{_libexecdi %{_libexecdir}/selinux/semanage_migrate_store %changelog +* Tue Mar 13 2018 Petr Lautrbach - 2.7-10 +- properly check return value of iterate function +- Use umask(0077) for fopen() write operations +- Return commit number if save-previous false +- Allow tmp files to be kept if a compile fails +- build: follow standard semantics for DESTDIR and PREFIX +- Improve warning for installing disabled module +- silence clang static analyzer report +- remove access() check to make setuid programs work + * Fri Feb 09 2018 Igor Gnatenko - 2.7-9 - Escape macros in %%changelog