File openssh-6.6p1-prevent_private_key_leakage.patch of Package openssh.10219

# HG changeset patch
# Parent  8c44bbed35a9beacbc1f647e5b4bb9f2501a4805
Pre-allocare buffer for private keys data to prevent leaking of sensitive data
via heap.

CVE-2016-10011
bsc#1016369

backported upstream commit 54d022026aae4f53fa74cc636e4a032d9689b64d
backported upstream commit a9c746088787549bb5b1ae3add7d06a1b6d93d5e

diff --git a/openssh-6.6p1/authfile.c b/openssh-6.6p1/authfile.c
--- a/openssh-6.6p1/authfile.c
+++ b/openssh-6.6p1/authfile.c
@@ -689,34 +689,44 @@ key_load_file(int fd, const char *filena
 	if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
 	    st.st_size > MAX_KEY_FILE_SIZE) {
  toobig:
 		error("%s: key file %.200s%stoo large", __func__,
 		    filename == NULL ? "" : filename,
 		    filename == NULL ? "" : " ");
 		return 0;
 	}
+	/*
+	 * 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 :) */
+	}
+	buffer_append_space(blob, st.st_size);
 	buffer_clear(blob);
 	for (;;) {
 		if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
 			if (errno == EPIPE)
 				break;
 			debug("%s: read from key file %.200s%sfailed: %.100s",
 			    __func__, filename == NULL ? "" : filename,
 			    filename == NULL ? "" : " ", strerror(errno));
 			buffer_clear(blob);
 			explicit_bzero(buf, sizeof(buf));
 			return 0;
 		}
-		buffer_append(blob, buf, len);
-		if (buffer_len(blob) > MAX_KEY_FILE_SIZE) {
+		/* first check limits to prevent automatic buffer blow-up */
+		if (buffer_len(blob) + len > (u_int)st.st_size) {
 			buffer_clear(blob);
 			explicit_bzero(buf, sizeof(buf));
 			goto toobig;
 		}
+		buffer_append(blob, buf, len);
 	}
 	explicit_bzero(buf, sizeof(buf));
 	if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
 	    st.st_size != buffer_len(blob)) {
 		debug("%s: key file %.200s%schanged size while reading",
 		    __func__, filename == NULL ? "" : filename,
 		    filename == NULL ? "" : " ");
 		buffer_clear(blob);
openSUSE Build Service is sponsored by