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