diff options
Diffstat (limited to 'meta/recipes-connectivity/openssh/openssh/CVE-2016-6210_p2.patch')
-rw-r--r-- | meta/recipes-connectivity/openssh/openssh/CVE-2016-6210_p2.patch | 110 |
1 files changed, 110 insertions, 0 deletions
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 @@ | |||
1 | From 283b97ff33ea2c641161950849931bd578de6946 Mon Sep 17 00:00:00 2001 | ||
2 | From: Darren Tucker <dtucker@zip.com.au> | ||
3 | Date: Fri, 15 Jul 2016 13:49:44 +1000 | ||
4 | Subject: [PATCH] Mitigate timing of disallowed users PAM logins. | ||
5 | |||
6 | When sshd decides to not allow a login (eg PermitRootLogin=no) and | ||
7 | it's using PAM, it sends a fake password to PAM so that the timing for | ||
8 | the failure is not noticeably different whether or not the password | ||
9 | is correct. This behaviour can be detected by sending a very long | ||
10 | password string which is slower to hash than the fake password. | ||
11 | |||
12 | Mitigate by constructing an invalid password that is the same length | ||
13 | as the one from the client and thus takes the same time to hash. | ||
14 | Diff from djm@ | ||
15 | |||
16 | Upstream-Status: Backport | ||
17 | CVE: CVE-2016-6210 patch2 | ||
18 | Signed-off-by: Armin Kuster <akuster@mvista.com> | ||
19 | |||
20 | --- | ||
21 | auth-pam.c | 35 +++++++++++++++++++++++++++++++---- | ||
22 | 1 file changed, 31 insertions(+), 4 deletions(-) | ||
23 | |||
24 | Index: 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); | ||