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

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