summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmin Kuster <akuster@mvista.com>2016-09-17 20:58:40 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-09-23 23:22:03 +0100
commitddb1db9ef7c9c2459c02c6f28fb4a1fda459bd2f (patch)
tree526c82a96be55cd35b1ab257ee709b5311ab43ad
parentfc1ba0b67fd614ad1603f7d5282e90bceef069c8 (diff)
downloadpoky-ddb1db9ef7c9c2459c02c6f28fb4a1fda459bd2f.tar.gz
openssh: Security fix CVE-2016-6210
affects openssh < 7.3 (From OE-Core rev: 7d07de3841c0a736262088c95a938deff194d9e2) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-connectivity/openssh/openssh/CVE-2016-6210.patch114
-rw-r--r--meta/recipes-connectivity/openssh/openssh/CVE-2016-6210_p2.patch110
-rw-r--r--meta/recipes-connectivity/openssh/openssh/CVE-2016-6210_p3.patch62
-rw-r--r--meta/recipes-connectivity/openssh/openssh_7.1p2.bb3
4 files changed, 289 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/openssh/openssh/CVE-2016-6210.patch b/meta/recipes-connectivity/openssh/openssh/CVE-2016-6210.patch
new file mode 100644
index 0000000000..e3072b43f5
--- /dev/null
+++ b/meta/recipes-connectivity/openssh/openssh/CVE-2016-6210.patch
@@ -0,0 +1,114 @@
1From 9286875a73b2de7736b5e50692739d314cd8d9dc Mon Sep 17 00:00:00 2001
2From: Darren Tucker <dtucker@zip.com.au>
3Date: Fri, 15 Jul 2016 13:32:45 +1000
4Subject: [PATCH] Determine appropriate salt for invalid users.
5
6When sshd is processing a non-PAM login for a non-existent user it uses
7the string from the fakepw structure as the salt for crypt(3)ing the
8password supplied by the client. That string has a Blowfish prefix, so on
9systems that don't understand that crypt will fail fast due to an invalid
10salt, and even on those that do it may have significantly different timing
11from the hash methods used for real accounts (eg sha512). This allows
12user enumeration by, eg, sending large password strings. This was noted
13by EddieEzra.Harari at verint.com (CVE-2016-6210).
14
15To mitigate, use the same hash algorithm that root uses for hashing
16passwords for users that do not exist on the system. ok djm@
17
18Upstream-Status: Backport
19OpenSSH < 7.3
20CVE: CVE-2016-6210 patch1
21Signed-off-by: Armin Kuster <akuster@mvista.com>
22
23---
24 auth-passwd.c | 12 ++++++++----
25 openbsd-compat/xcrypt.c | 34 ++++++++++++++++++++++++++++++++++
26 2 files changed, 42 insertions(+), 4 deletions(-)
27
28Index: openssh-7.1p2/auth-passwd.c
29===================================================================
30--- openssh-7.1p2.orig/auth-passwd.c
31+++ openssh-7.1p2/auth-passwd.c
32@@ -198,7 +198,7 @@ int
33 sys_auth_passwd(Authctxt *authctxt, const char *password)
34 {
35 struct passwd *pw = authctxt->pw;
36- char *encrypted_password;
37+ char *encrypted_password, *salt = NULL;
38
39 /* Just use the supplied fake password if authctxt is invalid */
40 char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;
41@@ -207,9 +207,13 @@ sys_auth_passwd(Authctxt *authctxt, cons
42 if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
43 return (1);
44
45- /* Encrypt the candidate password using the proper salt. */
46- encrypted_password = xcrypt(password,
47- (pw_password[0] && pw_password[1]) ? pw_password : "xx");
48+ /*
49+ * Encrypt the candidate password using the proper salt, or pass a
50+ * NULL and let xcrypt pick one.
51+ */
52+ if (authctxt->valid && pw_password[0] && pw_password[1])
53+ salt = pw_password;
54+ encrypted_password = xcrypt(password, salt);
55
56 /*
57 * Authentication is accepted if the encrypted passwords
58Index: openssh-7.1p2/openbsd-compat/xcrypt.c
59===================================================================
60--- openssh-7.1p2.orig/openbsd-compat/xcrypt.c
61+++ openssh-7.1p2/openbsd-compat/xcrypt.c
62@@ -25,6 +25,7 @@
63 #include "includes.h"
64
65 #include <sys/types.h>
66+#include <string.h>
67 #include <unistd.h>
68 #include <pwd.h>
69
70@@ -62,11 +63,44 @@
71 # define crypt DES_crypt
72 # endif
73
74+/*
75+ * Pick an appropriate password encryption type and salt for the running
76+ * system.
77+ */
78+static const char *
79+pick_salt(void)
80+{
81+ struct passwd *pw;
82+ char *passwd, *p;
83+ size_t typelen;
84+ static char salt[32];
85+
86+ if (salt[0] != '\0')
87+ return salt;
88+ strlcpy(salt, "xx", sizeof(salt));
89+ if ((pw = getpwuid(0)) == NULL)
90+ return salt;
91+ passwd = shadow_pw(pw);
92+ if (passwd[0] != '$' || (p = strrchr(passwd + 1, '$')) == NULL)
93+ return salt; /* no $, DES */
94+ typelen = p - passwd + 1;
95+ strlcpy(salt, passwd, MIN(typelen, sizeof(salt)));
96+ explicit_bzero(passwd, strlen(passwd));
97+ return salt;
98+}
99+
100 char *
101 xcrypt(const char *password, const char *salt)
102 {
103 char *crypted;
104
105+ /*
106+ * If we don't have a salt we are encrypting a fake password for
107+ * for timing purposes. Pick an appropriate salt.
108+ */
109+ if (salt == NULL)
110+ salt = pick_salt();
111+
112 # ifdef HAVE_MD5_PASSWORDS
113 if (is_md5_salt(salt))
114 crypted = md5_crypt(password, salt);
diff --git a/meta/recipes-connectivity/openssh/openssh/CVE-2016-6210_p2.patch b/meta/recipes-connectivity/openssh/openssh/CVE-2016-6210_p2.patch
new file mode 100644
index 0000000000..f27c74c7c1
--- /dev/null
+++ b/meta/recipes-connectivity/openssh/openssh/CVE-2016-6210_p2.patch
@@ -0,0 +1,110 @@
1From 283b97ff33ea2c641161950849931bd578de6946 Mon Sep 17 00:00:00 2001
2From: Darren Tucker <dtucker@zip.com.au>
3Date: Fri, 15 Jul 2016 13:49:44 +1000
4Subject: [PATCH] Mitigate timing of disallowed users PAM logins.
5
6When sshd decides to not allow a login (eg PermitRootLogin=no) and
7it's using PAM, it sends a fake password to PAM so that the timing for
8the failure is not noticeably different whether or not the password
9is correct. This behaviour can be detected by sending a very long
10password string which is slower to hash than the fake password.
11
12Mitigate by constructing an invalid password that is the same length
13as the one from the client and thus takes the same time to hash.
14Diff from djm@
15
16Upstream-Status: Backport
17CVE: CVE-2016-6210 patch2
18Signed-off-by: Armin Kuster <akuster@mvista.com>
19
20---
21 auth-pam.c | 35 +++++++++++++++++++++++++++++++----
22 1 file changed, 31 insertions(+), 4 deletions(-)
23
24Index: openssh-7.1p2/auth-pam.c
25===================================================================
26--- openssh-7.1p2.orig/auth-pam.c
27+++ openssh-7.1p2/auth-pam.c
28@@ -231,7 +231,6 @@ static int sshpam_account_status = -1;
29 static char **sshpam_env = NULL;
30 static Authctxt *sshpam_authctxt = NULL;
31 static const char *sshpam_password = NULL;
32-static char badpw[] = "\b\n\r\177INCORRECT";
33
34 /* Some PAM implementations don't implement this */
35 #ifndef HAVE_PAM_GETENVLIST
36@@ -809,12 +808,35 @@ sshpam_query(void *ctx, char **name, cha
37 return (-1);
38 }
39
40+/*
41+ * Returns a junk password of identical length to that the user supplied.
42+ * Used to mitigate timing attacks against crypt(3)/PAM stacks that
43+ * vary processing time in proportion to password length.
44+ */
45+static char *
46+fake_password(const char *wire_password)
47+{
48+ const char junk[] = "\b\n\r\177INCORRECT";
49+ char *ret = NULL;
50+ size_t i, l = wire_password != NULL ? strlen(wire_password) : 0;
51+
52+ if (l >= INT_MAX)
53+ fatal("%s: password length too long: %zu", __func__, l);
54+
55+ ret = malloc(l + 1);
56+ for (i = 0; i < l; i++)
57+ ret[i] = junk[i % (sizeof(junk) - 1)];
58+ ret[i] = '\0';
59+ return ret;
60+}
61+
62 /* XXX - see also comment in auth-chall.c:verify_response */
63 static int
64 sshpam_respond(void *ctx, u_int num, char **resp)
65 {
66 Buffer buffer;
67 struct pam_ctxt *ctxt = ctx;
68+ char *fake;
69
70 debug2("PAM: %s entering, %u responses", __func__, num);
71 switch (ctxt->pam_done) {
72@@ -835,8 +857,11 @@ sshpam_respond(void *ctx, u_int num, cha
73 (sshpam_authctxt->pw->pw_uid != 0 ||
74 options.permit_root_login == PERMIT_YES))
75 buffer_put_cstring(&buffer, *resp);
76- else
77- buffer_put_cstring(&buffer, badpw);
78+ else {
79+ fake = fake_password(*resp);
80+ buffer_put_cstring(&buffer, fake);
81+ free(fake);
82+ }
83 if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
84 buffer_free(&buffer);
85 return (-1);
86@@ -1180,6 +1205,7 @@ sshpam_auth_passwd(Authctxt *authctxt, c
87 {
88 int flags = (options.permit_empty_passwd == 0 ?
89 PAM_DISALLOW_NULL_AUTHTOK : 0);
90+ char *fake = NULL;
91
92 if (!options.use_pam || sshpam_handle == NULL)
93 fatal("PAM: %s called when PAM disabled or failed to "
94@@ -1195,7 +1221,7 @@ sshpam_auth_passwd(Authctxt *authctxt, c
95 */
96 if (!authctxt->valid || (authctxt->pw->pw_uid == 0 &&
97 options.permit_root_login != PERMIT_YES))
98- sshpam_password = badpw;
99+ sshpam_password = fake = fake_password(password);
100
101 sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
102 (const void *)&passwd_conv);
103@@ -1205,6 +1231,7 @@ sshpam_auth_passwd(Authctxt *authctxt, c
104
105 sshpam_err = pam_authenticate(sshpam_handle, flags);
106 sshpam_password = NULL;
107+ free(fake);
108 if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
109 debug("PAM: password authentication accepted for %.100s",
110 authctxt->user);
diff --git a/meta/recipes-connectivity/openssh/openssh/CVE-2016-6210_p3.patch b/meta/recipes-connectivity/openssh/openssh/CVE-2016-6210_p3.patch
new file mode 100644
index 0000000000..790ec808be
--- /dev/null
+++ b/meta/recipes-connectivity/openssh/openssh/CVE-2016-6210_p3.patch
@@ -0,0 +1,62 @@
1From dbf788b4d9d9490a5fff08a7b09888272bb10fcc Mon Sep 17 00:00:00 2001
2From: Darren Tucker <dtucker@zip.com.au>
3Date: Thu, 21 Jul 2016 14:17:31 +1000
4Subject: [PATCH] Search users for one with a valid salt.
5
6If the root account is locked (eg password "!!" or "*LK*") keep looking
7until we find a user with a valid salt to use for crypting passwords of
8invalid users. ok djm@
9
10Upstream-Status: Backport
11CVE: CVE-2016-6210
12Signed-off-by: Armin Kuster <akuster@mvista.com>
13
14---
15 openbsd-compat/xcrypt.c | 24 +++++++++++++++---------
16 1 file changed, 15 insertions(+), 9 deletions(-)
17
18diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c
19index 8913bb8..cf6a9b9 100644
20--- a/openbsd-compat/xcrypt.c
21+++ b/openbsd-compat/xcrypt.c
22@@ -65,7 +65,9 @@
23
24 /*
25 * Pick an appropriate password encryption type and salt for the running
26- * system.
27+ * system by searching through accounts until we find one that has a valid
28+ * salt. Usually this will be root unless the root account is locked out.
29+ * If we don't find one we return a traditional DES-based salt.
30 */
31 static const char *
32 pick_salt(void)
33@@ -78,14 +80,18 @@ pick_salt(void)
34 if (salt[0] != '\0')
35 return salt;
36 strlcpy(salt, "xx", sizeof(salt));
37- if ((pw = getpwuid(0)) == NULL)
38- return salt;
39- passwd = shadow_pw(pw);
40- if (passwd[0] != '$' || (p = strrchr(passwd + 1, '$')) == NULL)
41- return salt; /* no $, DES */
42- typelen = p - passwd + 1;
43- strlcpy(salt, passwd, MIN(typelen, sizeof(salt)));
44- explicit_bzero(passwd, strlen(passwd));
45+ setpwent();
46+ while ((pw = getpwent()) != NULL) {
47+ passwd = shadow_pw(pw);
48+ if (passwd[0] == '$' && (p = strrchr(passwd+1, '$')) != NULL) {
49+ typelen = p - passwd + 1;
50+ strlcpy(salt, passwd, MIN(typelen, sizeof(salt)));
51+ explicit_bzero(passwd, strlen(passwd));
52+ goto out;
53+ }
54+ }
55+ out:
56+ endpwent();
57 return salt;
58 }
59
60--
612.7.4
62
diff --git a/meta/recipes-connectivity/openssh/openssh_7.1p2.bb b/meta/recipes-connectivity/openssh/openssh_7.1p2.bb
index 56a1c8329a..bd047b0773 100644
--- a/meta/recipes-connectivity/openssh/openssh_7.1p2.bb
+++ b/meta/recipes-connectivity/openssh/openssh_7.1p2.bb
@@ -25,6 +25,9 @@ SRC_URI = "ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.tar.
25 file://CVE-2016-1907_2.patch \ 25 file://CVE-2016-1907_2.patch \
26 file://CVE-2016-1907_3.patch \ 26 file://CVE-2016-1907_3.patch \
27 file://CVE-2016-3115.patch \ 27 file://CVE-2016-3115.patch \
28 file://CVE-2016-6210.patch \
29 file://CVE-2016-6210_p2.patch \
30 file://CVE-2016-6210_p3.patch \
28 " 31 "
29 32
30PAM_SRC_URI = "file://sshd" 33PAM_SRC_URI = "file://sshd"