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

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