Merge openssh 7.5p1
BUG: 35443510
Change-Id: I2558fb80234e145c13ccb7a51859f2a5fd2e0324
diff --git a/authfile.c b/authfile.c
index 58f589a..7411b68 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.c,v 1.116 2015/07/09 09:49:46 markus Exp $ */
+/* $OpenBSD: authfile.c,v 1.122 2016/11/25 23:24:45 djm Exp $ */
/*
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
*
@@ -100,13 +100,25 @@
u_char buf[1024];
size_t len;
struct stat st;
- int r;
+ int r, dontmax = 0;
if (fstat(fd, &st) < 0)
return SSH_ERR_SYSTEM_ERROR;
if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
st.st_size > MAX_KEY_FILE_SIZE)
return SSH_ERR_INVALID_FORMAT;
+ /*
+ * Pre-allocate the buffer used for the key contents and clamp its
+ * maximum size. This ensures that key contents are never leaked via
+ * implicit realloc() in the sshbuf code.
+ */
+ if ((st.st_mode & S_IFREG) == 0 || st.st_size <= 0) {
+ st.st_size = 64*1024; /* 64k should be enough for anyone :) */
+ dontmax = 1;
+ }
+ if ((r = sshbuf_allocate(blob, st.st_size)) != 0 ||
+ (dontmax && (r = sshbuf_set_max_size(blob, st.st_size)) != 0))
+ return r;
for (;;) {
if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
if (errno == EPIPE)
@@ -147,7 +159,8 @@
struct sshbuf *b = NULL;
int r;
- *keyp = NULL;
+ if (keyp != NULL)
+ *keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
@@ -200,7 +213,8 @@
{
int fd, r;
- *keyp = NULL;
+ if (keyp != NULL)
+ *keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
@@ -231,6 +245,8 @@
struct sshbuf *buffer = NULL;
int r;
+ if (keyp != NULL)
+ *keyp = NULL;
if ((buffer = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
@@ -243,8 +259,7 @@
/* success */
r = 0;
out:
- if (buffer != NULL)
- sshbuf_free(buffer);
+ sshbuf_free(buffer);
return r;
}
@@ -256,7 +271,8 @@
struct sshbuf *buffer = NULL;
int r, fd;
- *keyp = NULL;
+ if (keyp != NULL)
+ *keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
@@ -272,14 +288,13 @@
goto out;
}
if ((r = sshkey_load_file(fd, buffer)) != 0 ||
- (r = sshkey_parse_private_fileblob(buffer, passphrase, filename,
- keyp, commentp)) != 0)
+ (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp,
+ commentp)) != 0)
goto out;
r = 0;
out:
close(fd);
- if (buffer != NULL)
- sshbuf_free(buffer);
+ sshbuf_free(buffer);
return r;
}
@@ -410,7 +425,8 @@
char *file = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
- *keyp = NULL;
+ if (keyp != NULL)
+ *keyp = NULL;
if (asprintf(&file, "%s-cert.pub", filename) == -1)
return SSH_ERR_ALLOC_FAIL;
@@ -420,16 +436,15 @@
}
if ((r = sshkey_try_load_public(pub, file, NULL)) != 0)
goto out;
-
- *keyp = pub;
- pub = NULL;
+ /* success */
+ if (keyp != NULL) {
+ *keyp = pub;
+ pub = NULL;
+ }
r = 0;
-
out:
- if (file != NULL)
- free(file);
- if (pub != NULL)
- sshkey_free(pub);
+ free(file);
+ sshkey_free(pub);
return r;
}
@@ -441,7 +456,8 @@
struct sshkey *key = NULL, *cert = NULL;
int r;
- *keyp = NULL;
+ if (keyp != NULL)
+ *keyp = NULL;
switch (type) {
#ifdef WITH_OPENSSL
@@ -471,13 +487,13 @@
(r = sshkey_cert_copy(cert, key)) != 0)
goto out;
r = 0;
- *keyp = key;
- key = NULL;
+ if (keyp != NULL) {
+ *keyp = key;
+ key = NULL;
+ }
out:
- if (key != NULL)
- sshkey_free(key);
- if (cert != NULL)
- sshkey_free(cert);
+ sshkey_free(key);
+ sshkey_free(cert);
return r;
}
@@ -538,8 +554,7 @@
}
r = SSH_ERR_KEY_NOT_FOUND;
out:
- if (pub != NULL)
- sshkey_free(pub);
+ sshkey_free(pub);
fclose(f);
return r;
}