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

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