Blob Blame History Raw
From e90a98395a8c4bc265067519c450360481dff1f3 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 11 Oct 2016 18:41:56 +0200
Subject: [PATCH 1/2] copyTruncate: factor out handling of SELinux context

... to separate functions

Closes #72

Upstream-commit: c5bff8adcece162746c68834fa1526dd45ca7bd0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 logrotate.c | 117 ++++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 74 insertions(+), 43 deletions(-)

diff --git a/logrotate.c b/logrotate.c
index 2abac3d..6270995 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -251,6 +251,72 @@ static unsigned hashIndex(const char *fn)
 	return hash % hashSize;
 }
 
+static int setSecCtx(int fdSrc, const char *src, void **pPrevCtx)
+{
+#ifdef WITH_SELINUX
+    security_context_t srcCtx;
+    *pPrevCtx = NULL;
+
+    if (!selinux_enabled)
+	/* pretend success */
+	return 0;
+
+    /* read security context of fdSrc */
+    if (fgetfilecon_raw(fdSrc, &srcCtx) < 0) {
+	if (errno == ENOTSUP)
+	    /* pretend success */
+	    return 0;
+
+	message(MESS_ERROR, "getting file context %s: %s\n", src,
+		strerror(errno));
+	return selinux_enforce;
+    }
+
+    /* save default security context for restoreSecCtx() */
+    if (getfscreatecon_raw((security_context_t *)pPrevCtx) < 0) {
+	message(MESS_ERROR, "getting default context: %s\n", strerror(errno));
+	return selinux_enforce;
+    }
+
+    /* set default security context to match fdSrc */
+    if (setfscreatecon_raw(srcCtx) < 0) {
+	message(MESS_ERROR, "setting default context to %s: %s\n", srcCtx,
+		strerror(errno));
+	freecon(srcCtx);
+	return selinux_enforce;
+    }
+
+    message(MESS_DEBUG, "set default create context to %s\n", srcCtx);
+    freecon(srcCtx);
+#else
+    (void) fdSrc;
+    (void) src;
+    (void) pPrevCtx;
+#endif
+    return 0;
+}
+
+static void restoreSecCtx(void **pPrevCtx)
+{
+#ifdef WITH_SELINUX
+    const security_context_t prevCtx = (security_context_t) *pPrevCtx;
+    if (!prevCtx)
+	/* no security context saved for restoration */
+	return;
+
+    /* set default security context to the previously stored one */
+    if (selinux_enabled && setfscreatecon_raw(prevCtx) < 0)
+	message(MESS_ERROR, "setting default context to %s: %s\n", prevCtx,
+		strerror(errno));
+
+    /* free the memory allocated to save the security context */
+    freecon(prevCtx);
+    *pPrevCtx = NULL;
+#else
+    (void) pPrevCtx;
+#endif
+}
+
 static struct logState *newState(const char *fn)
 {
 	struct tm now = *localtime(&nowSecs);
@@ -679,6 +745,7 @@ static int copyTruncate(char *currLog, char *saveLog, struct stat *sb,
 {
     char buf[BUFSIZ];
     int fdcurr = -1, fdsave = -1;
+    void *prevCtx;
     ssize_t cnt;
 
     message(MESS_DEBUG, "copying %s to %s\n", currLog, saveLog);
@@ -689,48 +756,18 @@ static int copyTruncate(char *currLog, char *saveLog, struct stat *sb,
 		    strerror(errno));
 	    return 1;
 	}
-#ifdef WITH_SELINUX
-	if (selinux_enabled) {
-	    security_context_t oldContext;
-	    if (fgetfilecon_raw(fdcurr, &oldContext) >= 0) {
-		if (getfscreatecon_raw(&prev_context) < 0) {
-		    message(MESS_ERROR,
-			    "getting default context: %s\n",
-			    strerror(errno));
-		    if (selinux_enforce) {
-				freecon(oldContext);
-				close(fdcurr);
-				return 1;
-		    }
-		}
-		if (setfscreatecon_raw(oldContext) < 0) {
-		    message(MESS_ERROR,
-			    "setting file context %s to %s: %s\n",
-			    saveLog, oldContext, strerror(errno));
-			if (selinux_enforce) {
-				freecon(oldContext);
-				close(fdcurr);
-				return 1;
-		    }
-		}
-		message(MESS_DEBUG, "set default create context\n");
-		freecon(oldContext);
-	    } else {
-		    if (errno != ENOTSUP) {
-			    message(MESS_ERROR, "getting file context %s: %s\n",
-				    currLog, strerror(errno));
-			    if (selinux_enforce) {
-				    return 1;
-			    }
-		    }
-	    }
+
+	if (setSecCtx(fdcurr, currLog, &prevCtx) != 0) {
+	    /* error msg already printed */
+	    close(fdcurr);
+	    return 1;
 	}
-#endif
 #ifdef WITH_ACL
 	if ((prev_acl = acl_get_fd(fdcurr)) == NULL) {
 		if (!ACL_NOT_WELL_SUPPORTED(errno)) {
 			message(MESS_ERROR, "getting file ACL %s: %s\n",
 				currLog, strerror(errno));
+			restoreSecCtx(&prevCtx);
 			close(fdcurr);
 			return 1;
 		}
@@ -738,13 +775,7 @@ static int copyTruncate(char *currLog, char *saveLog, struct stat *sb,
 #endif /* WITH_ACL */
 	fdsave =
 	    createOutputFile(saveLog, O_WRONLY | O_CREAT, sb, prev_acl, 0);
-#ifdef WITH_SELINUX
-	if (selinux_enabled) {
-	    setfscreatecon_raw(prev_context);
-		freecon(prev_context);
-		prev_context = NULL;
-	}
-#endif
+	restoreSecCtx(&prevCtx);
 #ifdef WITH_ACL
 	if (prev_acl) {
 		acl_free(prev_acl);
-- 
2.7.4


From 0ed7a45533a3d9d2237c742a2de03faba1b2e35f Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 11 Oct 2016 18:53:18 +0200
Subject: [PATCH 2/2] compressLogFile: explicitly preserve SELinux context

If we use options 'compress' and 'sharedscripts' together, the rotated
(and compressed) log files may end up with a wrong security context in
case multiple files with different security contexts are rotated in a
row.

Closes #72

Upstream-commit: 57458d5424eebf0c7912eefe955e4d7b0f49fd15
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 logrotate.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/logrotate.c b/logrotate.c
index 6270995..20f6ea5 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -558,6 +558,7 @@ static int compressLogFile(char *name, struct logInfo *log, struct stat *sb)
     int outFile;
     int i;
     int status;
+    void *prevCtx;
 
     message(MESS_DEBUG, "compressing log with: %s\n", log->compress_prog);
     if (debug)
@@ -578,11 +579,18 @@ static int compressLogFile(char *name, struct logInfo *log, struct stat *sb)
 	return 1;
     }
 
+    if (setSecCtx(inFile, name, &prevCtx) != 0) {
+	/* error msg already printed */
+	close(inFile);
+	return 1;
+    }
+
 #ifdef WITH_ACL
 	if ((prev_acl = acl_get_fd(inFile)) == NULL) {
 		if (!ACL_NOT_WELL_SUPPORTED(errno)) {
 			message(MESS_ERROR, "getting file ACL %s: %s\n",
 				name, strerror(errno));
+			restoreSecCtx(&prevCtx);
 			close(inFile);
 			return 1;
 		}
@@ -591,6 +599,7 @@ static int compressLogFile(char *name, struct logInfo *log, struct stat *sb)
 
     outFile =
 	createOutputFile(compressedName, O_RDWR | O_CREAT, sb, prev_acl, 0);
+    restoreSecCtx(&prevCtx);
 #ifdef WITH_ACL
 	if (prev_acl) {
 		acl_free(prev_acl);
-- 
2.7.4