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

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