Blame SPECS/0003-libsemanage-fsync-final-files-before-rename.patch

Packit Service 102278
From dc4f1d03d6e17d851283f9b10b2faeeca9b10e14 Mon Sep 17 00:00:00 2001
Packit Service 102278
From: Stephen Smalley <stephen.smalley.work@gmail.com>
Packit Service 102278
Date: Wed, 13 May 2020 15:34:19 -0400
Packit Service 102278
Subject: [PATCH] libsemanage: fsync final files before rename
Packit Service 102278
Packit Service 102278
Prior to rename(2)'ing the final selinux policy files into place,
Packit Service 102278
fsync(2) them to ensure the contents will be fully written prior to
Packit Service 102278
rename.  While we are here, also fix checking of write(2) to detect
Packit Service 102278
short writes and treat them as an error.  This code could be more
Packit Service 102278
generally improved but keeping to the minimal changes required to fix
Packit Service 102278
this bug.
Packit Service 102278
Packit Service 102278
Fixes: https://github.com/SELinuxProject/selinux/issues/237
Packit Service 102278
Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Packit Service 102278
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Packit Service 102278
Packit Service 102278
Source:
Packit Service 102278
https://github.com/SELinuxProject/selinux/commit/331a109f91ea46473fd858c2494f6eab1ef43f66
Packit Service 102278
---
Packit Service 102278
 libsemanage/src/direct_api.c     | 10 +++++-----
Packit Service 102278
 libsemanage/src/semanage_store.c | 20 +++++++++++++++-----
Packit Service 102278
 libsemanage/src/semanage_store.h |  4 +++-
Packit Service 102278
 3 files changed, 23 insertions(+), 11 deletions(-)
Packit Service 102278
Packit Service 102278
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
Packit Service 102278
index 8e4d116d..abc3a4cb 100644
Packit Service 102278
--- a/libsemanage/src/direct_api.c
Packit Service 102278
+++ b/libsemanage/src/direct_api.c
Packit Service 102278
@@ -1188,7 +1188,7 @@ cleanup:
Packit Service 102278
  * overwrite it. If source doesn't exist then return success.
Packit Service 102278
  * Returns 0 on success, -1 on error. */
Packit Service 102278
 static int copy_file_if_exists(const char *src, const char *dst, mode_t mode){
Packit Service 102278
-	int rc = semanage_copy_file(src, dst, mode);
Packit Service 102278
+	int rc = semanage_copy_file(src, dst, mode, false);
Packit Service 102278
 	return (rc < 0 && errno != ENOENT) ? rc : 0;
Packit Service 102278
 }
Packit Service 102278
 
Packit Service 102278
@@ -1481,7 +1481,7 @@ rebuild:
Packit Service 102278
 			retval = semanage_copy_file(path,
Packit Service 102278
 						    semanage_path(SEMANAGE_TMP,
Packit Service 102278
 								  SEMANAGE_STORE_SEUSERS),
Packit Service 102278
-						    0);
Packit Service 102278
+						    0, false);
Packit Service 102278
 			if (retval < 0)
Packit Service 102278
 				goto cleanup;
Packit Service 102278
 			pseusers->dtable->drop_cache(pseusers->dbase);
Packit Service 102278
@@ -1499,7 +1499,7 @@ rebuild:
Packit Service 102278
 			retval = semanage_copy_file(path,
Packit Service 102278
 						    semanage_path(SEMANAGE_TMP,
Packit Service 102278
 								  SEMANAGE_USERS_EXTRA),
Packit Service 102278
-						    0);
Packit Service 102278
+						    0, false);
Packit Service 102278
 			if (retval < 0)
Packit Service 102278
 				goto cleanup;
Packit Service 102278
 			pusers_extra->dtable->drop_cache(pusers_extra->dbase);
Packit Service 102278
@@ -1588,7 +1588,7 @@ rebuild:
Packit Service 102278
 
Packit Service 102278
 	retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
Packit Service 102278
 			semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL),
Packit Service 102278
-			sh->conf->file_mode);
Packit Service 102278
+			sh->conf->file_mode, false);
Packit Service 102278
 	if (retval < 0) {
Packit Service 102278
 		goto cleanup;
Packit Service 102278
 	}
Packit Service 102278
@@ -1627,7 +1627,7 @@ rebuild:
Packit Service 102278
 			retval = semanage_copy_file(
Packit Service 102278
 						semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS),
Packit Service 102278
 						semanage_final_path(SEMANAGE_FINAL_TMP,	SEMANAGE_FC_HOMEDIRS),
Packit Service 102278
-						sh->conf->file_mode);
Packit Service 102278
+						sh->conf->file_mode, false);
Packit Service 102278
 			if (retval < 0) {
Packit Service 102278
 				goto cleanup;
Packit Service 102278
 			}
Packit Service 102278
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
Packit Service 102278
index 58dded6e..733df8da 100644
Packit Service 102278
--- a/libsemanage/src/semanage_store.c
Packit Service 102278
+++ b/libsemanage/src/semanage_store.c
Packit Service 102278
@@ -707,7 +707,8 @@ static int semanage_filename_select(const struct dirent *d)
Packit Service 102278
 
Packit Service 102278
 /* Copies a file from src to dst.  If dst already exists then
Packit Service 102278
  * overwrite it.  Returns 0 on success, -1 on error. */
Packit Service 102278
-int semanage_copy_file(const char *src, const char *dst, mode_t mode)
Packit Service 102278
+int semanage_copy_file(const char *src, const char *dst, mode_t mode,
Packit Service 102278
+		bool syncrequired)
Packit Service 102278
 {
Packit Service 102278
 	int in, out, retval = 0, amount_read, n, errsv = errno;
Packit Service 102278
 	char tmp[PATH_MAX];
Packit Service 102278
@@ -735,8 +736,11 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode)
Packit Service 102278
 	}
Packit Service 102278
 	umask(mask);
Packit Service 102278
 	while (retval == 0 && (amount_read = read(in, buf, sizeof(buf))) > 0) {
Packit Service 102278
-		if (write(out, buf, amount_read) < 0) {
Packit Service 102278
-			errsv = errno;
Packit Service 102278
+		if (write(out, buf, amount_read) != amount_read) {
Packit Service 102278
+			if (errno)
Packit Service 102278
+				errsv = errno;
Packit Service 102278
+			else
Packit Service 102278
+				errsv = EIO;
Packit Service 102278
 			retval = -1;
Packit Service 102278
 		}
Packit Service 102278
 	}
Packit Service 102278
@@ -745,6 +749,10 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode)
Packit Service 102278
 		retval = -1;
Packit Service 102278
 	}
Packit Service 102278
 	close(in);
Packit Service 102278
+	if (syncrequired && fsync(out) < 0) {
Packit Service 102278
+		errsv = errno;
Packit Service 102278
+		retval = -1;
Packit Service 102278
+	}
Packit Service 102278
 	if (close(out) < 0) {
Packit Service 102278
 		errsv = errno;
Packit Service 102278
 		retval = -1;
Packit Service 102278
@@ -811,7 +819,8 @@ static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
Packit Service 102278
 			umask(mask);
Packit Service 102278
 		} else if (S_ISREG(sb.st_mode) && flag == 1) {
Packit Service 102278
 			mask = umask(0077);
Packit Service 102278
-			if (semanage_copy_file(path, path2, sb.st_mode) < 0) {
Packit Service 102278
+			if (semanage_copy_file(path, path2, sb.st_mode,
Packit Service 102278
+						false) < 0) {
Packit Service 102278
 				umask(mask);
Packit Service 102278
 				goto cleanup;
Packit Service 102278
 			}
Packit Service 102278
@@ -1640,7 +1649,8 @@ static int semanage_install_final_tmp(semanage_handle_t * sh)
Packit Service 102278
 			goto cleanup;
Packit Service 102278
 		}
Packit Service 102278
 
Packit Service 102278
-		ret = semanage_copy_file(src, dst, sh->conf->file_mode);
Packit Service 102278
+		ret = semanage_copy_file(src, dst, sh->conf->file_mode,
Packit Service 102278
+					true);
Packit Service 102278
 		if (ret < 0) {
Packit Service 102278
 			ERR(sh, "Could not copy %s to %s.", src, dst);
Packit Service 102278
 			goto cleanup;
Packit Service 102278
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
Packit Service 102278
index 34bf8523..b9ec5664 100644
Packit Service 102278
--- a/libsemanage/src/semanage_store.h
Packit Service 102278
+++ b/libsemanage/src/semanage_store.h
Packit Service 102278
@@ -24,6 +24,7 @@
Packit Service 102278
 #ifndef SEMANAGE_MODULE_STORE_H
Packit Service 102278
 #define SEMANAGE_MODULE_STORE_H
Packit Service 102278
 
Packit Service 102278
+#include <stdbool.h>
Packit Service 102278
 #include <sys/time.h>
Packit Service 102278
 #include <sepol/module.h>
Packit Service 102278
 #include <sepol/cil/cil.h>
Packit Service 102278
@@ -162,6 +163,7 @@ int semanage_nc_sort(semanage_handle_t * sh,
Packit Service 102278
 		     size_t buf_len,
Packit Service 102278
 		     char **sorted_buf, size_t * sorted_buf_len);
Packit Service 102278
 
Packit Service 102278
-int semanage_copy_file(const char *src, const char *dst, mode_t mode);
Packit Service 102278
+int semanage_copy_file(const char *src, const char *dst, mode_t mode,
Packit Service 102278
+		bool syncrequired);
Packit Service 102278
 
Packit Service 102278
 #endif
Packit Service 102278
-- 
Packit Service 102278
2.25.4
Packit Service 102278