summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2016-11-25 23:24:45 +0000
committerDamien Miller <djm@mindrot.org>2016-11-29 16:48:02 +1100
commit54d022026aae4f53fa74cc636e4a032d9689b64d (patch)
tree03417de4bf21ae2982f1dd047f444e96c780a5c5 /authfile.c
parenta9c746088787549bb5b1ae3add7d06a1b6d93d5e (diff)
upstream commit
use sshbuf_allocate() to pre-allocate the buffer used for loading keys. This avoids implicit realloc inside the buffer code, which might theoretically leave fragments of the key on the heap. This doesn't appear to happen in practice for normal sized keys, but was observed for novelty oversize ones. Pointed out by Jann Horn of Project Zero; ok markus@ Upstream-ID: d620e1d46a29fdea56aeadeda120879eddc60ab1
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/authfile.c b/authfile.c
index f46b4e37f..7411b68f6 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.121 2016/04/09 12:39:30 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.122 2016/11/25 23:24:45 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
4 * 4 *
@@ -100,13 +100,25 @@ sshkey_load_file(int fd, struct sshbuf *blob)
100 u_char buf[1024]; 100 u_char buf[1024];
101 size_t len; 101 size_t len;
102 struct stat st; 102 struct stat st;
103 int r; 103 int r, dontmax = 0;
104 104
105 if (fstat(fd, &st) < 0) 105 if (fstat(fd, &st) < 0)
106 return SSH_ERR_SYSTEM_ERROR; 106 return SSH_ERR_SYSTEM_ERROR;
107 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && 107 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
108 st.st_size > MAX_KEY_FILE_SIZE) 108 st.st_size > MAX_KEY_FILE_SIZE)
109 return SSH_ERR_INVALID_FORMAT; 109 return SSH_ERR_INVALID_FORMAT;
110 /*
111 * Pre-allocate the buffer used for the key contents and clamp its
112 * maximum size. This ensures that key contents are never leaked via
113 * implicit realloc() in the sshbuf code.
114 */
115 if ((st.st_mode & S_IFREG) == 0 || st.st_size <= 0) {
116 st.st_size = 64*1024; /* 64k should be enough for anyone :) */
117 dontmax = 1;
118 }
119 if ((r = sshbuf_allocate(blob, st.st_size)) != 0 ||
120 (dontmax && (r = sshbuf_set_max_size(blob, st.st_size)) != 0))
121 return r;
110 for (;;) { 122 for (;;) {
111 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) { 123 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
112 if (errno == EPIPE) 124 if (errno == EPIPE)