diff options
author | djm@openbsd.org <djm@openbsd.org> | 2016-11-25 23:24:45 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2016-11-29 16:48:02 +1100 |
commit | 54d022026aae4f53fa74cc636e4a032d9689b64d (patch) | |
tree | 03417de4bf21ae2982f1dd047f444e96c780a5c5 | |
parent | a9c746088787549bb5b1ae3add7d06a1b6d93d5e (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
-rw-r--r-- | authfile.c | 16 |
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) |