diff options
author | Leonardo Arena <rnalrd@alpinelinux.org> | 2019-03-01 09:15:30 +0000 |
---|---|---|
committer | Leonardo Arena <rnalrd@alpinelinux.org> | 2019-03-04 07:40:56 +0000 |
commit | e231e6bed510c2304f37093f0eadb5708da9728e (patch) | |
tree | 1410763dde20515814a760dd17bc6b1091ce9dc0 | |
parent | 3743142601832292353277ae7bcbe4b04c1c56d9 (diff) | |
download | alpine_aports-e231e6bed510c2304f37093f0eadb5708da9728e.tar.bz2 alpine_aports-e231e6bed510c2304f37093f0eadb5708da9728e.tar.xz alpine_aports-e231e6bed510c2304f37093f0eadb5708da9728e.zip |
main/openssh: security fixes
CVE-2018-20685, CVE-2019-6109, CVE-2019-6111
Rebase HPN patch
Fixes #9996
-rw-r--r-- | main/openssh/APKBUILD | 15 | ||||
-rw-r--r-- | main/openssh/CVE-2018-20685.patch | 33 | ||||
-rw-r--r-- | main/openssh/CVE-2019-6109.patch | 276 | ||||
-rw-r--r-- | main/openssh/CVE-2019-6111.patch | 187 | ||||
-rw-r--r-- | main/openssh/openssh7.4-peaktput.patch | 19 |
5 files changed, 519 insertions, 11 deletions
diff --git a/main/openssh/APKBUILD b/main/openssh/APKBUILD index fced60459e..9503f60e82 100644 --- a/main/openssh/APKBUILD +++ b/main/openssh/APKBUILD | |||
@@ -4,7 +4,7 @@ | |||
4 | pkgname=openssh | 4 | pkgname=openssh |
5 | pkgver=7.9_p1 | 5 | pkgver=7.9_p1 |
6 | _myver=${pkgver%_*}${pkgver#*_} | 6 | _myver=${pkgver%_*}${pkgver#*_} |
7 | pkgrel=2 | 7 | pkgrel=3 |
8 | pkgdesc="Port of OpenBSD's free SSH release" | 8 | pkgdesc="Port of OpenBSD's free SSH release" |
9 | url="https://www.openssh.org/portable.html" | 9 | url="https://www.openssh.org/portable.html" |
10 | arch="all" | 10 | arch="all" |
@@ -30,15 +30,23 @@ for _flavour in $_pkgsupport; do | |||
30 | done | 30 | done |
31 | 31 | ||
32 | source="https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/$pkgname-$_myver.tar.gz | 32 | source="https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/$pkgname-$_myver.tar.gz |
33 | CVE-2018-20685.patch | ||
34 | CVE-2019-6109.patch | ||
35 | CVE-2019-6111.patch | ||
33 | openssh7.4-peaktput.patch | 36 | openssh7.4-peaktput.patch |
34 | fix-utmp.patch | 37 | fix-utmp.patch |
35 | bsd-compatible-realpath.patch | 38 | bsd-compatible-realpath.patch |
36 | sftp-interactive.patch | 39 | sftp-interactive.patch |
37 | disable-forwarding-by-default.patch | 40 | disable-forwarding-by-default.patch |
41 | |||
38 | sshd.initd | 42 | sshd.initd |
39 | sshd.confd | 43 | sshd.confd |
40 | " | 44 | " |
41 | # secfixes: | 45 | # secfixes: |
46 | # 7.9_p1-r3: | ||
47 | # - CVE-2018-20685 | ||
48 | # - CVE-2019-6109 | ||
49 | # - CVE-2019-6111 | ||
42 | # 7.7_p1-r4: | 50 | # 7.7_p1-r4: |
43 | # - CVE-2018-15473 | 51 | # - CVE-2018-15473 |
44 | # 7.5_p1-r8: | 52 | # 7.5_p1-r8: |
@@ -197,7 +205,10 @@ _pkg_flavour() { | |||
197 | } | 205 | } |
198 | 206 | ||
199 | sha512sums="0412c9c429c9287f0794023951469c8e6ec833cdb55821bfa0300dd90d0879ff60484f620cffd93372641ab69bf0b032c2d700ccc680950892725fb631b7708e openssh-7.9p1.tar.gz | 207 | sha512sums="0412c9c429c9287f0794023951469c8e6ec833cdb55821bfa0300dd90d0879ff60484f620cffd93372641ab69bf0b032c2d700ccc680950892725fb631b7708e openssh-7.9p1.tar.gz |
200 | 398096a89aa104abeff31aa043ac406a6348e0fdd4d313b7888ee0b931d38fd71fc21bceee46145e88f03bc27e00890e068442faee2d33f86cfbc04d58ffa4b6 openssh7.4-peaktput.patch | 208 | b8907d3d6ebceeca15f6bc97551a7613c68df5c31e4e76d43b7c0bd9ad42dedcabc20a2cc5404b89f40850a4765b24892bde50eab1db55c96ad5cf23bb1f8d04 CVE-2018-20685.patch |
209 | 299e24dbe73d170d16769fa46e52045e034ff8eb2e7ed26bf2e29d941f067ebbe7e66f4a1253576d13ef689922ac2948215ecd744f57a362cb175549080f41ca CVE-2019-6109.patch | ||
210 | 7b321e7ff7cff7fb956efd30d3ee770eb553e2db8d0d5e613624859f877efe55da8989f03cdf9e206b397bbc9b6b584c4374073af1a524981e8420c72daf648c CVE-2019-6111.patch | ||
211 | 7b5ec0c18117437d8ed5132e13b29d604b49a11c571ee89316d1adeb457092379130b9af6b97effa6b2d05d5d5512cf82ebf76803c29cbc5ab387bf87bafd7b9 openssh7.4-peaktput.patch | ||
201 | f35fffcd26635249ce5d820e7b3e406e586f2d2d7f6a045f221e2f9fb53aebc1ab1dd1e603b3389462296ed77921a1d08456e7aaa3825cbed08f405b381a58e1 fix-utmp.patch | 212 | f35fffcd26635249ce5d820e7b3e406e586f2d2d7f6a045f221e2f9fb53aebc1ab1dd1e603b3389462296ed77921a1d08456e7aaa3825cbed08f405b381a58e1 fix-utmp.patch |
202 | f2b8daa537ea3f32754a4485492cc6eb3f40133ed46c0a5a29a89e4bcf8583d82d891d94bf2e5eb1c916fa68ec094abf4e6cd641e9737a6c05053808012b3a73 bsd-compatible-realpath.patch | 213 | f2b8daa537ea3f32754a4485492cc6eb3f40133ed46c0a5a29a89e4bcf8583d82d891d94bf2e5eb1c916fa68ec094abf4e6cd641e9737a6c05053808012b3a73 bsd-compatible-realpath.patch |
203 | c1d09c65dbc347f0904edc30f91aa9a24b0baee50309536182455b544f1e3f85a8cecfa959e32be8b101d8282ef06dde3febbbc3f315489339dcf04155c859a9 sftp-interactive.patch | 214 | c1d09c65dbc347f0904edc30f91aa9a24b0baee50309536182455b544f1e3f85a8cecfa959e32be8b101d8282ef06dde3febbbc3f315489339dcf04155c859a9 sftp-interactive.patch |
diff --git a/main/openssh/CVE-2018-20685.patch b/main/openssh/CVE-2018-20685.patch new file mode 100644 index 0000000000..f2f1ecfc55 --- /dev/null +++ b/main/openssh/CVE-2018-20685.patch | |||
@@ -0,0 +1,33 @@ | |||
1 | From 6010c0303a422a9c5fa8860c061bf7105eb7f8b2 Mon Sep 17 00:00:00 2001 | ||
2 | From: "djm@openbsd.org" <djm@openbsd.org> | ||
3 | Date: Fri, 16 Nov 2018 03:03:10 +0000 | ||
4 | Subject: [PATCH] upstream: disallow empty incoming filename or ones that refer | ||
5 | to the | ||
6 | |||
7 | current directory; based on report/patch from Harry Sintonen | ||
8 | |||
9 | OpenBSD-Commit-ID: f27651b30eaee2df49540ab68d030865c04f6de9 | ||
10 | --- | ||
11 | scp.c | 5 +++-- | ||
12 | 1 file changed, 3 insertions(+), 2 deletions(-) | ||
13 | |||
14 | diff --git a/scp.c b/scp.c | ||
15 | index 60682c687..4f3fdcd3d 100644 | ||
16 | --- a/scp.c | ||
17 | +++ b/scp.c | ||
18 | @@ -1,4 +1,4 @@ | ||
19 | -/* $OpenBSD: scp.c,v 1.197 2018/06/01 04:31:48 dtucker Exp $ */ | ||
20 | +/* $OpenBSD: scp.c,v 1.198 2018/11/16 03:03:10 djm Exp $ */ | ||
21 | /* | ||
22 | * scp - secure remote copy. This is basically patched BSD rcp which | ||
23 | * uses ssh to do the data transfer (instead of using rcmd). | ||
24 | @@ -1106,7 +1106,8 @@ sink(int argc, char **argv) | ||
25 | SCREWUP("size out of range"); | ||
26 | size = (off_t)ull; | ||
27 | |||
28 | - if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { | ||
29 | + if (*cp == '\0' || strchr(cp, '/') != NULL || | ||
30 | + strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) { | ||
31 | run_err("error: unexpected filename: %s", cp); | ||
32 | exit(1); | ||
33 | } | ||
diff --git a/main/openssh/CVE-2019-6109.patch b/main/openssh/CVE-2019-6109.patch new file mode 100644 index 0000000000..e58b8b1bd5 --- /dev/null +++ b/main/openssh/CVE-2019-6109.patch | |||
@@ -0,0 +1,276 @@ | |||
1 | From 11b88754cadcad0ba79b4ffcc127223248dccb54 Mon Sep 17 00:00:00 2001 | ||
2 | From: "dtucker@openbsd.org" <dtucker@openbsd.org> | ||
3 | Date: Wed, 23 Jan 2019 08:01:46 +0000 | ||
4 | Subject: upstream: Sanitize scp filenames via snmprintf. To do this we move | ||
5 | |||
6 | the progressmeter formatting outside of signal handler context and have the | ||
7 | atomicio callback called for EINTR too. bz#2434 with contributions from djm | ||
8 | and jjelen at redhat.com, ok djm@ | ||
9 | |||
10 | OpenBSD-Commit-ID: 1af61c1f70e4f3bd8ab140b9f1fa699481db57d8 | ||
11 | |||
12 | CVE-2019-6109 | ||
13 | |||
14 | Origin: backport, https://anongit.mindrot.org/openssh.git/commit/?id=8976f1c4b2721c26e878151f52bdf346dfe2d54c | ||
15 | Bug-Debian: https://bugs.debian.org/793412 | ||
16 | Last-Update: 2019-02-08 | ||
17 | |||
18 | Patch-Name: sanitize-scp-filenames-via-snmprintf.patch | ||
19 | --- | ||
20 | atomicio.c | 20 ++++++++++++++----- | ||
21 | progressmeter.c | 53 ++++++++++++++++++++++--------------------------- | ||
22 | progressmeter.h | 3 ++- | ||
23 | scp.c | 1 + | ||
24 | sftp-client.c | 16 ++++++++------- | ||
25 | 5 files changed, 51 insertions(+), 42 deletions(-) | ||
26 | |||
27 | diff --git a/atomicio.c b/atomicio.c | ||
28 | index f854a06f5..d91bd7621 100644 | ||
29 | --- a/atomicio.c | ||
30 | +++ b/atomicio.c | ||
31 | @@ -1,4 +1,4 @@ | ||
32 | -/* $OpenBSD: atomicio.c,v 1.28 2016/07/27 23:18:12 djm Exp $ */ | ||
33 | +/* $OpenBSD: atomicio.c,v 1.29 2019/01/23 08:01:46 dtucker Exp $ */ | ||
34 | /* | ||
35 | * Copyright (c) 2006 Damien Miller. All rights reserved. | ||
36 | * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. | ||
37 | @@ -65,9 +65,14 @@ atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n, | ||
38 | res = (f) (fd, s + pos, n - pos); | ||
39 | switch (res) { | ||
40 | case -1: | ||
41 | - if (errno == EINTR) | ||
42 | + if (errno == EINTR) { | ||
43 | + /* possible SIGALARM, update callback */ | ||
44 | + if (cb != NULL && cb(cb_arg, 0) == -1) { | ||
45 | + errno = EINTR; | ||
46 | + return pos; | ||
47 | + } | ||
48 | continue; | ||
49 | - if (errno == EAGAIN || errno == EWOULDBLOCK) { | ||
50 | + } else if (errno == EAGAIN || errno == EWOULDBLOCK) { | ||
51 | #ifndef BROKEN_READ_COMPARISON | ||
52 | (void)poll(&pfd, 1, -1); | ||
53 | #endif | ||
54 | @@ -122,9 +127,14 @@ atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd, | ||
55 | res = (f) (fd, iov, iovcnt); | ||
56 | switch (res) { | ||
57 | case -1: | ||
58 | - if (errno == EINTR) | ||
59 | + if (errno == EINTR) { | ||
60 | + /* possible SIGALARM, update callback */ | ||
61 | + if (cb != NULL && cb(cb_arg, 0) == -1) { | ||
62 | + errno = EINTR; | ||
63 | + return pos; | ||
64 | + } | ||
65 | continue; | ||
66 | - if (errno == EAGAIN || errno == EWOULDBLOCK) { | ||
67 | + } else if (errno == EAGAIN || errno == EWOULDBLOCK) { | ||
68 | #ifndef BROKEN_READV_COMPARISON | ||
69 | (void)poll(&pfd, 1, -1); | ||
70 | #endif | ||
71 | diff --git a/progressmeter.c b/progressmeter.c | ||
72 | index fe9bf52e4..add462dde 100644 | ||
73 | --- a/progressmeter.c | ||
74 | +++ b/progressmeter.c | ||
75 | @@ -1,4 +1,4 @@ | ||
76 | -/* $OpenBSD: progressmeter.c,v 1.45 2016/06/30 05:17:05 dtucker Exp $ */ | ||
77 | +/* $OpenBSD: progressmeter.c,v 1.46 2019/01/23 08:01:46 dtucker Exp $ */ | ||
78 | /* | ||
79 | * Copyright (c) 2003 Nils Nordman. All rights reserved. | ||
80 | * | ||
81 | @@ -31,6 +31,7 @@ | ||
82 | |||
83 | #include <errno.h> | ||
84 | #include <signal.h> | ||
85 | +#include <stdarg.h> | ||
86 | #include <stdio.h> | ||
87 | #include <string.h> | ||
88 | #include <time.h> | ||
89 | @@ -39,6 +40,7 @@ | ||
90 | #include "progressmeter.h" | ||
91 | #include "atomicio.h" | ||
92 | #include "misc.h" | ||
93 | +#include "utf8.h" | ||
94 | |||
95 | #define DEFAULT_WINSIZE 80 | ||
96 | #define MAX_WINSIZE 512 | ||
97 | @@ -61,7 +63,7 @@ static void setscreensize(void); | ||
98 | void refresh_progress_meter(void); | ||
99 | |||
100 | /* signal handler for updating the progress meter */ | ||
101 | -static void update_progress_meter(int); | ||
102 | +static void sig_alarm(int); | ||
103 | |||
104 | static double start; /* start progress */ | ||
105 | static double last_update; /* last progress update */ | ||
106 | @@ -74,6 +76,7 @@ static long stalled; /* how long we have been stalled */ | ||
107 | static int bytes_per_second; /* current speed in bytes per second */ | ||
108 | static int win_size; /* terminal window size */ | ||
109 | static volatile sig_atomic_t win_resized; /* for window resizing */ | ||
110 | +static volatile sig_atomic_t alarm_fired; | ||
111 | |||
112 | /* units for format_size */ | ||
113 | static const char unit[] = " KMGT"; | ||
114 | @@ -126,9 +129,17 @@ refresh_progress_meter(void) | ||
115 | off_t bytes_left; | ||
116 | int cur_speed; | ||
117 | int hours, minutes, seconds; | ||
118 | - int i, len; | ||
119 | int file_len; | ||
120 | |||
121 | + if ((!alarm_fired && !win_resized) || !can_output()) | ||
122 | + return; | ||
123 | + alarm_fired = 0; | ||
124 | + | ||
125 | + if (win_resized) { | ||
126 | + setscreensize(); | ||
127 | + win_resized = 0; | ||
128 | + } | ||
129 | + | ||
130 | transferred = *counter - (cur_pos ? cur_pos : start_pos); | ||
131 | cur_pos = *counter; | ||
132 | now = monotime_double(); | ||
133 | @@ -158,16 +169,11 @@ refresh_progress_meter(void) | ||
134 | |||
135 | /* filename */ | ||
136 | buf[0] = '\0'; | ||
137 | - file_len = win_size - 35; | ||
138 | + file_len = win_size - 36; | ||
139 | if (file_len > 0) { | ||
140 | - len = snprintf(buf, file_len + 1, "\r%s", file); | ||
141 | - if (len < 0) | ||
142 | - len = 0; | ||
143 | - if (len >= file_len + 1) | ||
144 | - len = file_len; | ||
145 | - for (i = len; i < file_len; i++) | ||
146 | - buf[i] = ' '; | ||
147 | - buf[file_len] = '\0'; | ||
148 | + buf[0] = '\r'; | ||
149 | + snmprintf(buf+1, sizeof(buf)-1 , &file_len, "%*s", | ||
150 | + file_len * -1, file); | ||
151 | } | ||
152 | |||
153 | /* percent of transfer done */ | ||
154 | @@ -228,22 +234,11 @@ refresh_progress_meter(void) | ||
155 | |||
156 | /*ARGSUSED*/ | ||
157 | static void | ||
158 | -update_progress_meter(int ignore) | ||
159 | +sig_alarm(int ignore) | ||
160 | { | ||
161 | - int save_errno; | ||
162 | - | ||
163 | - save_errno = errno; | ||
164 | - | ||
165 | - if (win_resized) { | ||
166 | - setscreensize(); | ||
167 | - win_resized = 0; | ||
168 | - } | ||
169 | - if (can_output()) | ||
170 | - refresh_progress_meter(); | ||
171 | - | ||
172 | - signal(SIGALRM, update_progress_meter); | ||
173 | + signal(SIGALRM, sig_alarm); | ||
174 | + alarm_fired = 1; | ||
175 | alarm(UPDATE_INTERVAL); | ||
176 | - errno = save_errno; | ||
177 | } | ||
178 | |||
179 | void | ||
180 | @@ -259,10 +254,9 @@ start_progress_meter(const char *f, off_t filesize, off_t *ctr) | ||
181 | bytes_per_second = 0; | ||
182 | |||
183 | setscreensize(); | ||
184 | - if (can_output()) | ||
185 | - refresh_progress_meter(); | ||
186 | + refresh_progress_meter(); | ||
187 | |||
188 | - signal(SIGALRM, update_progress_meter); | ||
189 | + signal(SIGALRM, sig_alarm); | ||
190 | signal(SIGWINCH, sig_winch); | ||
191 | alarm(UPDATE_INTERVAL); | ||
192 | } | ||
193 | @@ -286,6 +280,7 @@ stop_progress_meter(void) | ||
194 | static void | ||
195 | sig_winch(int sig) | ||
196 | { | ||
197 | + signal(SIGWINCH, sig_winch); | ||
198 | win_resized = 1; | ||
199 | } | ||
200 | |||
201 | diff --git a/progressmeter.h b/progressmeter.h | ||
202 | index bf179dca6..8f6678060 100644 | ||
203 | --- a/progressmeter.h | ||
204 | +++ b/progressmeter.h | ||
205 | @@ -1,4 +1,4 @@ | ||
206 | -/* $OpenBSD: progressmeter.h,v 1.3 2015/01/14 13:54:13 djm Exp $ */ | ||
207 | +/* $OpenBSD: progressmeter.h,v 1.4 2019/01/23 08:01:46 dtucker Exp $ */ | ||
208 | /* | ||
209 | * Copyright (c) 2002 Nils Nordman. All rights reserved. | ||
210 | * | ||
211 | @@ -24,4 +24,5 @@ | ||
212 | */ | ||
213 | |||
214 | void start_progress_meter(const char *, off_t, off_t *); | ||
215 | +void refresh_progress_meter(void); | ||
216 | void stop_progress_meter(void); | ||
217 | diff --git a/scp.c b/scp.c | ||
218 | index 7163d33dc..80308573c 100644 | ||
219 | --- a/scp.c | ||
220 | +++ b/scp.c | ||
221 | @@ -593,6 +593,7 @@ scpio(void *_cnt, size_t s) | ||
222 | off_t *cnt = (off_t *)_cnt; | ||
223 | |||
224 | *cnt += s; | ||
225 | + refresh_progress_meter(); | ||
226 | if (limit_kbps > 0) | ||
227 | bandwidth_limit(&bwlimit, s); | ||
228 | return 0; | ||
229 | diff --git a/sftp-client.c b/sftp-client.c | ||
230 | index 4986d6d8d..2bc698f86 100644 | ||
231 | --- a/sftp-client.c | ||
232 | +++ b/sftp-client.c | ||
233 | @@ -101,7 +101,9 @@ sftpio(void *_bwlimit, size_t amount) | ||
234 | { | ||
235 | struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit; | ||
236 | |||
237 | - bandwidth_limit(bwlimit, amount); | ||
238 | + refresh_progress_meter(); | ||
239 | + if (bwlimit != NULL) | ||
240 | + bandwidth_limit(bwlimit, amount); | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | @@ -121,8 +123,8 @@ send_msg(struct sftp_conn *conn, struct sshbuf *m) | ||
245 | iov[1].iov_base = (u_char *)sshbuf_ptr(m); | ||
246 | iov[1].iov_len = sshbuf_len(m); | ||
247 | |||
248 | - if (atomiciov6(writev, conn->fd_out, iov, 2, | ||
249 | - conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) != | ||
250 | + if (atomiciov6(writev, conn->fd_out, iov, 2, sftpio, | ||
251 | + conn->limit_kbps > 0 ? &conn->bwlimit_out : NULL) != | ||
252 | sshbuf_len(m) + sizeof(mlen)) | ||
253 | fatal("Couldn't send packet: %s", strerror(errno)); | ||
254 | |||
255 | @@ -138,8 +140,8 @@ get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial) | ||
256 | |||
257 | if ((r = sshbuf_reserve(m, 4, &p)) != 0) | ||
258 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
259 | - if (atomicio6(read, conn->fd_in, p, 4, | ||
260 | - conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) { | ||
261 | + if (atomicio6(read, conn->fd_in, p, 4, sftpio, | ||
262 | + conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) != 4) { | ||
263 | if (errno == EPIPE || errno == ECONNRESET) | ||
264 | fatal("Connection closed"); | ||
265 | else | ||
266 | @@ -157,8 +159,8 @@ get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial) | ||
267 | |||
268 | if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) | ||
269 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
270 | - if (atomicio6(read, conn->fd_in, p, msg_len, | ||
271 | - conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) | ||
272 | + if (atomicio6(read, conn->fd_in, p, msg_len, sftpio, | ||
273 | + conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) | ||
274 | != msg_len) { | ||
275 | if (errno == EPIPE) | ||
276 | fatal("Connection closed"); | ||
diff --git a/main/openssh/CVE-2019-6111.patch b/main/openssh/CVE-2019-6111.patch new file mode 100644 index 0000000000..519358ce6c --- /dev/null +++ b/main/openssh/CVE-2019-6111.patch | |||
@@ -0,0 +1,187 @@ | |||
1 | From 125924e47db3713a85a70e0f8d6c23818d2ea054 Mon Sep 17 00:00:00 2001 | ||
2 | From: "djm@openbsd.org" <djm@openbsd.org> | ||
3 | Date: Sat, 26 Jan 2019 22:41:28 +0000 | ||
4 | Subject: upstream: check in scp client that filenames sent during | ||
5 | |||
6 | remote->local directory copies satisfy the wildcard specified by the user. | ||
7 | |||
8 | This checking provides some protection against a malicious server | ||
9 | sending unexpected filenames, but it comes at a risk of rejecting wanted | ||
10 | files due to differences between client and server wildcard expansion rules. | ||
11 | |||
12 | For this reason, this also adds a new -T flag to disable the check. | ||
13 | |||
14 | reported by Harry Sintonen | ||
15 | fix approach suggested by markus@; | ||
16 | has been in snaps for ~1wk courtesy deraadt@ | ||
17 | |||
18 | OpenBSD-Commit-ID: 00f44b50d2be8e321973f3c6d014260f8f7a8eda | ||
19 | |||
20 | CVE-2019-6111 | ||
21 | |||
22 | Origin: backport, https://anongit.mindrot.org/openssh.git/commit/?id=391ffc4b9d31fa1f4ad566499fef9176ff8a07dc | ||
23 | Last-Update: 2019-02-08 | ||
24 | |||
25 | Patch-Name: check-filenames-in-scp-client.patch | ||
26 | --- | ||
27 | scp.1 | 12 +++++++++++- | ||
28 | scp.c | 37 +++++++++++++++++++++++++++++-------- | ||
29 | 2 files changed, 40 insertions(+), 9 deletions(-) | ||
30 | |||
31 | diff --git a/scp.1 b/scp.1 | ||
32 | index 0e5cc1b2d..397e77091 100644 | ||
33 | --- a/scp.1 | ||
34 | +++ b/scp.1 | ||
35 | @@ -18,7 +18,7 @@ | ||
36 | .Nd secure copy (remote file copy program) | ||
37 | .Sh SYNOPSIS | ||
38 | .Nm scp | ||
39 | -.Op Fl 346BCpqrv | ||
40 | +.Op Fl 346BCpqrTv | ||
41 | .Op Fl c Ar cipher | ||
42 | .Op Fl F Ar ssh_config | ||
43 | .Op Fl i Ar identity_file | ||
44 | @@ -208,6 +208,16 @@ to use for the encrypted connection. | ||
45 | The program must understand | ||
46 | .Xr ssh 1 | ||
47 | options. | ||
48 | +.It Fl T | ||
49 | +Disable strict filename checking. | ||
50 | +By default when copying files from a remote host to a local directory | ||
51 | +.Nm | ||
52 | +checks that the received filenames match those requested on the command-line | ||
53 | +to prevent the remote end from sending unexpected or unwanted files. | ||
54 | +Because of differences in how various operating systems and shells interpret | ||
55 | +filename wildcards, these checks may cause wanted files to be rejected. | ||
56 | +This option disables these checks at the expense of fully trusting that | ||
57 | +the server will not send unexpected filenames. | ||
58 | .It Fl v | ||
59 | Verbose mode. | ||
60 | Causes | ||
61 | diff --git a/scp.c b/scp.c | ||
62 | index 1971c80cd..035037bcc 100644 | ||
63 | --- a/scp.c | ||
64 | +++ b/scp.c | ||
65 | @@ -94,6 +94,7 @@ | ||
66 | #include <dirent.h> | ||
67 | #include <errno.h> | ||
68 | #include <fcntl.h> | ||
69 | +#include <fnmatch.h> | ||
70 | #include <limits.h> | ||
71 | #include <locale.h> | ||
72 | #include <pwd.h> | ||
73 | @@ -383,14 +384,14 @@ void verifydir(char *); | ||
74 | struct passwd *pwd; | ||
75 | uid_t userid; | ||
76 | int errs, remin, remout; | ||
77 | -int pflag, iamremote, iamrecursive, targetshouldbedirectory; | ||
78 | +int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory; | ||
79 | |||
80 | #define CMDNEEDS 64 | ||
81 | char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ | ||
82 | |||
83 | int response(void); | ||
84 | void rsource(char *, struct stat *); | ||
85 | -void sink(int, char *[]); | ||
86 | +void sink(int, char *[], const char *); | ||
87 | void source(int, char *[]); | ||
88 | void tolocal(int, char *[]); | ||
89 | void toremote(int, char *[]); | ||
90 | @@ -429,8 +430,9 @@ main(int argc, char **argv) | ||
91 | addargs(&args, "-oRemoteCommand=none"); | ||
92 | addargs(&args, "-oRequestTTY=no"); | ||
93 | |||
94 | - fflag = tflag = 0; | ||
95 | - while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1) | ||
96 | + fflag = Tflag = tflag = 0; | ||
97 | + while ((ch = getopt(argc, argv, | ||
98 | + "dfl:prtTvBCc:i:P:q12346S:o:F:")) != -1) { | ||
99 | switch (ch) { | ||
100 | /* User-visible flags. */ | ||
101 | case '1': | ||
102 | @@ -509,9 +511,13 @@ main(int argc, char **argv) | ||
103 | setmode(0, O_BINARY); | ||
104 | #endif | ||
105 | break; | ||
106 | + case 'T': | ||
107 | + Tflag = 1; | ||
108 | + break; | ||
109 | default: | ||
110 | usage(); | ||
111 | } | ||
112 | + } | ||
113 | argc -= optind; | ||
114 | argv += optind; | ||
115 | |||
116 | @@ -542,7 +548,7 @@ main(int argc, char **argv) | ||
117 | } | ||
118 | if (tflag) { | ||
119 | /* Receive data. */ | ||
120 | - sink(argc, argv); | ||
121 | + sink(argc, argv, NULL); | ||
122 | exit(errs != 0); | ||
123 | } | ||
124 | if (argc < 2) | ||
125 | @@ -800,7 +806,7 @@ tolocal(int argc, char **argv) | ||
126 | continue; | ||
127 | } | ||
128 | free(bp); | ||
129 | - sink(1, argv + argc - 1); | ||
130 | + sink(1, argv + argc - 1, src); | ||
131 | (void) close(remin); | ||
132 | remin = remout = -1; | ||
133 | } | ||
134 | @@ -976,7 +982,7 @@ rsource(char *name, struct stat *statp) | ||
135 | (sizeof(type) != 4 && sizeof(type) != 8)) | ||
136 | |||
137 | void | ||
138 | -sink(int argc, char **argv) | ||
139 | +sink(int argc, char **argv, const char *src) | ||
140 | { | ||
141 | static BUF buffer; | ||
142 | struct stat stb; | ||
143 | @@ -992,6 +998,7 @@ sink(int argc, char **argv) | ||
144 | unsigned long long ull; | ||
145 | int setimes, targisdir, wrerrno = 0; | ||
146 | char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; | ||
147 | + char *src_copy = NULL, *restrict_pattern = NULL; | ||
148 | struct timeval tv[2]; | ||
149 | |||
150 | #define atime tv[0] | ||
151 | @@ -1016,6 +1023,17 @@ sink(int argc, char **argv) | ||
152 | (void) atomicio(vwrite, remout, "", 1); | ||
153 | if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) | ||
154 | targisdir = 1; | ||
155 | + if (src != NULL && !iamrecursive && !Tflag) { | ||
156 | + /* | ||
157 | + * Prepare to try to restrict incoming filenames to match | ||
158 | + * the requested destination file glob. | ||
159 | + */ | ||
160 | + if ((src_copy = strdup(src)) == NULL) | ||
161 | + fatal("strdup failed"); | ||
162 | + if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) { | ||
163 | + *restrict_pattern++ = '\0'; | ||
164 | + } | ||
165 | + } | ||
166 | for (first = 1;; first = 0) { | ||
167 | cp = buf; | ||
168 | if (atomicio(read, remin, cp, 1) != 1) | ||
169 | @@ -1120,6 +1138,9 @@ sink(int argc, char **argv) | ||
170 | run_err("error: unexpected filename: %s", cp); | ||
171 | exit(1); | ||
172 | } | ||
173 | + if (restrict_pattern != NULL && | ||
174 | + fnmatch(restrict_pattern, cp, 0) != 0) | ||
175 | + SCREWUP("filename does not match request"); | ||
176 | if (targisdir) { | ||
177 | static char *namebuf; | ||
178 | static size_t cursize; | ||
179 | @@ -1157,7 +1178,7 @@ sink(int argc, char **argv) | ||
180 | goto bad; | ||
181 | } | ||
182 | vect[0] = xstrdup(np); | ||
183 | - sink(1, vect); | ||
184 | + sink(1, vect, src); | ||
185 | if (setimes) { | ||
186 | setimes = 0; | ||
187 | if (utimes(vect[0], tv) < 0) | ||
diff --git a/main/openssh/openssh7.4-peaktput.patch b/main/openssh/openssh7.4-peaktput.patch index 6fc6140a6e..ec76deb3b4 100644 --- a/main/openssh/openssh7.4-peaktput.patch +++ b/main/openssh/openssh7.4-peaktput.patch | |||
@@ -9,14 +9,15 @@ | |||
9 | static volatile off_t *counter; /* progress counter */ | 9 | static volatile off_t *counter; /* progress counter */ |
10 | static long stalled; /* how long we have been stalled */ | 10 | static long stalled; /* how long we have been stalled */ |
11 | static int bytes_per_second; /* current speed in bytes per second */ | 11 | static int bytes_per_second; /* current speed in bytes per second */ |
12 | @@ -128,12 +130,17 @@ | 12 | @@ -132,6 +132,7 @@ refresh_progress_meter(void) |
13 | int cur_speed; | ||
13 | int hours, minutes, seconds; | 14 | int hours, minutes, seconds; |
14 | int i, len; | ||
15 | int file_len; | 15 | int file_len; |
16 | + off_t delta_pos; | 16 | + off_t delta_pos; |
17 | 17 | ||
18 | transferred = *counter - (cur_pos ? cur_pos : start_pos); | 18 | if ((!alarm_fired && !win_resized) || !can_output()) |
19 | cur_pos = *counter; | 19 | return; |
20 | @@ -147,6 +148,10 @@ refresh_progress_meter(void) | ||
20 | now = monotime_double(); | 21 | now = monotime_double(); |
21 | bytes_left = end_pos - cur_pos; | 22 | bytes_left = end_pos - cur_pos; |
22 | 23 | ||
@@ -27,15 +28,15 @@ | |||
27 | if (bytes_left > 0) | 28 | if (bytes_left > 0) |
28 | elapsed = now - last_update; | 29 | elapsed = now - last_update; |
29 | else { | 30 | else { |
30 | @@ -158,7 +165,7 @@ | 31 | @@ -171,7 +176,7 @@ refresh_progress_meter(void) |
31 | 32 | ||
32 | /* filename */ | 33 | /* filename */ |
33 | buf[0] = '\0'; | 34 | buf[0] = '\0'; |
34 | - file_len = win_size - 35; | 35 | - file_len = win_size - 36; |
35 | + file_len = win_size - 45; | 36 | + file_len = win_size - 46; |
36 | if (file_len > 0) { | 37 | if (file_len > 0) { |
37 | len = snprintf(buf, file_len + 1, "\r%s", file); | 38 | buf[0] = '\r'; |
38 | if (len < 0) | 39 | snmprintf(buf+1, sizeof(buf)-1 , &file_len, "%*s", |
39 | @@ -188,6 +195,15 @@ | 40 | @@ -188,6 +195,15 @@ |
40 | (off_t)bytes_per_second); | 41 | (off_t)bytes_per_second); |
41 | strlcat(buf, "/s ", win_size); | 42 | strlcat(buf, "/s ", win_size); |