[gnutls-devel] [PATCH] _gnutls_resolve_priorities: always try to re-read sys priority file

Daniel P. Berrange berrange at redhat.com
Fri Jun 3 15:59:11 CEST 2016


Previously if the system priority file was edited, that would
take effect on the very next TLS session an application created.

As of:

  commit 006b89d4464ae1bb6d545ea5716998654124df45
  Author: Nikos Mavrogiannopoulos <nmav at redhat.com>
  Date:   Fri Apr 1 10:46:12 2016 +0200

    priorities: preload the system priorities on library loading time

It is required to restart every application after changing the
system priority file to get changes to take effect.

Further, for applications running in a chroot, it will no longer
honour a system priority file that may exist inside the chroot,
always using the originally cached data from outside the chroot.

This patch changes the caching so that we always try to reload
the cache of system priorities. A mtime check is used to avoid
actually re-reading the file unless its content has obviously
changed. If the file no longer exists, the cache will not be
invalidated. This ensures that the current priority file is
always honoured, whether inside a chroot or not, while at the
same time allowing apps to work in a chroot when no system
priority file is present.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 lib/priority.c | 55 +++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 45 insertions(+), 10 deletions(-)

diff --git a/lib/priority.c b/lib/priority.c
index 14b6251..5fcc97f 100644
--- a/lib/priority.c
+++ b/lib/priority.c
@@ -32,6 +32,7 @@
 #include <c-ctype.h>
 #include <extensions.h>
 #include "fips.h"
+#include "errno.h"
 
 #define MAX_ELEMENTS 64
 
@@ -926,26 +927,54 @@ static char *check_str(char *line, size_t line_size, const char *needle, size_t
 static const char *system_priority_file = SYSTEM_PRIORITY_FILE;
 static char *system_priority_buf = NULL;
 static size_t system_priority_buf_size = 0;
+static time_t system_priority_last_mod = 0;
 
-void _gnutls_load_system_priorities(void)
+
+static void _gnutls_update_system_priorities(void)
 {
+#ifdef HAVE_FMEMOPEN
 	gnutls_datum_t data;
-	const char *p;
 	int ret;
+	struct stat sb;
 
-	p = secure_getenv("GNUTLS_SYSTEM_PRIORITY_FILE");
-	if (p != NULL)
-		system_priority_file = p;
+	if (stat(system_priority_file, &sb) < 0) {
+		_gnutls_debug_log("unable to access: %s: %d\n",
+				  system_priority_file, errno);
+		return;
+	}
+
+	if (sb.st_mtime == system_priority_last_mod) {
+		_gnutls_debug_log("system priority %s has not changed\n",
+				  system_priority_file);
+		return;
+	}
 
-#ifdef HAVE_FMEMOPEN
 	ret = gnutls_load_file(system_priority_file, &data);
-	if (ret < 0)
+	if (ret < 0) {
+		_gnutls_debug_log("unable to load: %s: %d\n",
+				  system_priority_file, ret);
 		return;
+	}
 
+	_gnutls_debug_log("cached system priority %s mtime %lld\n",
+			  system_priority_file,
+			  (unsigned long long)sb.st_mtime);
+	gnutls_free(system_priority_buf);
 	system_priority_buf = (char*)data.data;
 	system_priority_buf_size = data.size;
+	system_priority_last_mod = sb.st_mtime;
 #endif
-	return;
+}
+
+void _gnutls_load_system_priorities(void)
+{
+	const char *p;
+
+	p = secure_getenv("GNUTLS_SYSTEM_PRIORITY_FILE");
+	if (p != NULL)
+		system_priority_file = p;
+
+	_gnutls_update_system_priorities();
 }
 
 void _gnutls_unload_system_priorities(void)
@@ -955,6 +984,7 @@ void _gnutls_unload_system_priorities(void)
 #endif
 	system_priority_buf = NULL;
 	system_priority_buf_size = 0;
+	system_priority_last_mod = 0;
 }
 
 /* Returns the new priorities if SYSTEM is specified in
@@ -990,10 +1020,15 @@ size_t n, n2 = 0, line_size;
 		}
 
 #ifdef HAVE_FMEMOPEN
+		/* Always try to refresh the cached data, to
+		 * allow it to be updated without restarting
+		 * all applications
+		 */
+		_gnutls_update_system_priorities();
 		fp = fmemopen(system_priority_buf, system_priority_buf_size, "r");
+#else
+		fp = fopen(system_priority_file, "r");
 #endif
-		if (fp == NULL)
-			fp = fopen(system_priority_file, "r");
 		if (fp == NULL) {/* fail */
 			ret = NULL;
 			goto finish;
-- 
2.5.5




More information about the Gnutls-devel mailing list