summaryrefslogtreecommitdiff
path: root/debian/patches/CVE-2016-6210-2.patch
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2016-07-22 14:09:29 +0100
committerColin Watson <cjwatson@debian.org>2016-07-22 14:11:33 +0100
commit5ebf9c1d19aa0d9d20781bab05e9d73d8addecb3 (patch)
tree7d48ac2d5442eff8ca63a0dd6938651e05b9c7c3 /debian/patches/CVE-2016-6210-2.patch
parent79139a04a0183cd47f3e837fa76fe5d51e62fcc9 (diff)
parentabde8dda29c2db2405d6fbca2fe022430e2c1177 (diff)
CVE-2016-6210: Mitigate user enumeration via covert timing channel.
Diffstat (limited to 'debian/patches/CVE-2016-6210-2.patch')
-rw-r--r--debian/patches/CVE-2016-6210-2.patch111
1 files changed, 111 insertions, 0 deletions
diff --git a/debian/patches/CVE-2016-6210-2.patch b/debian/patches/CVE-2016-6210-2.patch
new file mode 100644
index 000000000..1c580f90b
--- /dev/null
+++ b/debian/patches/CVE-2016-6210-2.patch
@@ -0,0 +1,111 @@
1From dde63f7f998ac3812a26bbb2c1b2947f24fcd060 Mon Sep 17 00:00:00 2001
2From: Darren Tucker <dtucker@zip.com.au>
3Date: Fri, 15 Jul 2016 13:49:44 +1000
4Subject: 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
16Origin: upstream, https://anongit.mindrot.org/openssh.git/commit/?id=283b97ff33ea2c641161950849931bd578de6946
17Bug-Debian: https://bugs.debian.org/831902
18Last-Update: 2016-07-22
19
20Patch-Name: CVE-2016-6210-2.patch
21---
22 auth-pam.c | 35 +++++++++++++++++++++++++++++++----
23 1 file changed, 31 insertions(+), 4 deletions(-)
24
25diff --git a/auth-pam.c b/auth-pam.c
26index 8425af1..abd6a5e 100644
27--- a/auth-pam.c
28+++ b/auth-pam.c
29@@ -232,7 +232,6 @@ static int sshpam_account_status = -1;
30 static char **sshpam_env = NULL;
31 static Authctxt *sshpam_authctxt = NULL;
32 static const char *sshpam_password = NULL;
33-static char badpw[] = "\b\n\r\177INCORRECT";
34
35 /* Some PAM implementations don't implement this */
36 #ifndef HAVE_PAM_GETENVLIST
37@@ -810,12 +809,35 @@ sshpam_query(void *ctx, char **name, char **info,
38 return (-1);
39 }
40
41+/*
42+ * Returns a junk password of identical length to that the user supplied.
43+ * Used to mitigate timing attacks against crypt(3)/PAM stacks that
44+ * vary processing time in proportion to password length.
45+ */
46+static char *
47+fake_password(const char *wire_password)
48+{
49+ const char junk[] = "\b\n\r\177INCORRECT";
50+ char *ret = NULL;
51+ size_t i, l = wire_password != NULL ? strlen(wire_password) : 0;
52+
53+ if (l >= INT_MAX)
54+ fatal("%s: password length too long: %zu", __func__, l);
55+
56+ ret = malloc(l + 1);
57+ for (i = 0; i < l; i++)
58+ ret[i] = junk[i % (sizeof(junk) - 1)];
59+ ret[i] = '\0';
60+ return ret;
61+}
62+
63 /* XXX - see also comment in auth-chall.c:verify_response */
64 static int
65 sshpam_respond(void *ctx, u_int num, char **resp)
66 {
67 Buffer buffer;
68 struct pam_ctxt *ctxt = ctx;
69+ char *fake;
70
71 debug2("PAM: %s entering, %u responses", __func__, num);
72 switch (ctxt->pam_done) {
73@@ -836,8 +858,11 @@ sshpam_respond(void *ctx, u_int num, char **resp)
74 (sshpam_authctxt->pw->pw_uid != 0 ||
75 options.permit_root_login == PERMIT_YES))
76 buffer_put_cstring(&buffer, *resp);
77- else
78- buffer_put_cstring(&buffer, badpw);
79+ else {
80+ fake = fake_password(*resp);
81+ buffer_put_cstring(&buffer, fake);
82+ free(fake);
83+ }
84 if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
85 buffer_free(&buffer);
86 return (-1);
87@@ -1181,6 +1206,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
88 {
89 int flags = (options.permit_empty_passwd == 0 ?
90 PAM_DISALLOW_NULL_AUTHTOK : 0);
91+ char *fake = NULL;
92
93 if (!options.use_pam || sshpam_handle == NULL)
94 fatal("PAM: %s called when PAM disabled or failed to "
95@@ -1196,7 +1222,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
96 */
97 if (!authctxt->valid || (authctxt->pw->pw_uid == 0 &&
98 options.permit_root_login != PERMIT_YES))
99- sshpam_password = badpw;
100+ sshpam_password = fake = fake_password(password);
101
102 sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
103 (const void *)&passwd_conv);
104@@ -1206,6 +1232,7 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
105
106 sshpam_err = pam_authenticate(sshpam_handle, flags);
107 sshpam_password = NULL;
108+ free(fake);
109 if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
110 debug("PAM: password authentication accepted for %.100s",
111 authctxt->user);