Blame SOURCES/0010-generate_hash-generate_pw_hash-don-t-use-strlen-for-.patch

112f40
From 57f7c776dca0322fab107460cac71ac4b6e79b9a Mon Sep 17 00:00:00 2001
112f40
From: Peter Jones <pjones@redhat.com>
112f40
Date: Tue, 15 May 2018 11:20:15 -0400
112f40
Subject: [PATCH 10/10] generate_hash() / generate_pw_hash(): don't use
112f40
 strlen() for strncpy bounds
112f40
112f40
New gcc rightly comlplains when we do the following:
112f40
112f40
strncpy (dest, src, strlen(src));
112f40
112f40
For two reasons:
112f40
a) it doesn't copy the NUL byte
112f40
b) it's otherwise the same thing strcpy() would have done
112f40
112f40
This patch replaces that with stpncpy (just because it's slightly easier
112f40
to use) and the real bounds for the destination.
112f40
112f40
Signed-off-by: Peter Jones <pjones@redhat.com>
112f40
---
112f40
 src/mokutil.c | 33 ++++++++++++++++++++++-----------
112f40
 1 file changed, 22 insertions(+), 11 deletions(-)
112f40
112f40
diff --git a/src/mokutil.c b/src/mokutil.c
112f40
index 0be9e8491fd..b5080107600 100644
112f40
--- a/src/mokutil.c
112f40
+++ b/src/mokutil.c
112f40
@@ -764,9 +764,10 @@ generate_hash (pw_crypt_t *pw_crypt, char *password, unsigned int pw_len)
112f40
 {
112f40
 	pw_crypt_t new_crypt;
112f40
 	char settings[SETTINGS_LEN];
112f40
+	char *next;
112f40
 	char *crypt_string;
112f40
 	const char *prefix;
112f40
-	int hash_len, prefix_len;
112f40
+	int hash_len, settings_len = sizeof (settings) - 2;
112f40
 
112f40
 	if (!password || !pw_crypt || password[pw_len] != '\0')
112f40
 		return -1;
112f40
@@ -774,15 +775,19 @@ generate_hash (pw_crypt_t *pw_crypt, char *password, unsigned int pw_len)
112f40
 	prefix = get_crypt_prefix (pw_crypt->method);
112f40
 	if (!prefix)
112f40
 		return -1;
112f40
-	prefix_len = strlen(prefix);
112f40
 
112f40
 	pw_crypt->salt_size = get_salt_size (pw_crypt->method);
112f40
 	generate_salt ((char *)pw_crypt->salt, pw_crypt->salt_size);
112f40
 
112f40
-	strncpy (settings, prefix, prefix_len);
112f40
-	strncpy (settings + prefix_len, (const char *)pw_crypt->salt,
112f40
-		 pw_crypt->salt_size);
112f40
-	settings[pw_crypt->salt_size + prefix_len] = '\0';
112f40
+	memset (settings, 0, sizeof (settings));
112f40
+	next = stpncpy (settings, prefix, settings_len);
112f40
+	if (pw_crypt->salt_size > settings_len - (next - settings)) {
112f40
+		errno = EOVERFLOW;
112f40
+		return -1;
112f40
+	}
112f40
+	next = stpncpy (next, (const char *)pw_crypt->salt,
112f40
+			pw_crypt->salt_size);
112f40
+	*next = '\0';
112f40
 
112f40
 	crypt_string = crypt (password, settings);
112f40
 	if (!crypt_string)
112f40
@@ -1929,10 +1934,11 @@ static int
112f40
 generate_pw_hash (const char *input_pw)
112f40
 {
112f40
 	char settings[SETTINGS_LEN];
112f40
+        char *next;
112f40
 	char *password = NULL;
112f40
 	char *crypt_string;
112f40
 	const char *prefix;
112f40
-	int prefix_len;
112f40
+	int settings_len = sizeof (settings) - 2;
112f40
 	unsigned int pw_len, salt_size;
112f40
 
112f40
 	if (input_pw) {
112f40
@@ -1958,12 +1964,17 @@ generate_pw_hash (const char *input_pw)
112f40
 	prefix = get_crypt_prefix (DEFAULT_CRYPT_METHOD);
112f40
 	if (!prefix)
112f40
 		return -1;
112f40
-	prefix_len = strlen(prefix);
112f40
 
112f40
-	strncpy (settings, prefix, prefix_len);
112f40
+	memset (settings, 0, sizeof (settings));
112f40
+	next = stpncpy (settings, prefix, settings_len);
112f40
 	salt_size = get_salt_size (DEFAULT_CRYPT_METHOD);
112f40
-	generate_salt ((settings + prefix_len), salt_size);
112f40
-	settings[DEFAULT_SALT_SIZE + prefix_len] = '\0';
112f40
+	if (salt_size > settings_len - (next - settings)) {
112f40
+		errno = EOVERFLOW;
112f40
+		return -1;
112f40
+	}
112f40
+	generate_salt (next, salt_size);
112f40
+	next += salt_size;
112f40
+	*next = '\0';
112f40
 
112f40
 	crypt_string = crypt (password, settings);
112f40
 	free (password);
112f40
-- 
112f40
2.17.1
112f40