diff -Nru openssh-5.9p1/debian/changelog openssh-5.9p1/debian/changelog --- openssh-5.9p1/debian/changelog 2016-01-13 15:49:17.000000000 +0000 +++ openssh-5.9p1/debian/changelog 2016-05-05 12:43:04.000000000 +0000 @@ -1,3 +1,24 @@ +openssh (1:5.9p1-5ubuntu1.9) precise-security; urgency=medium + + * SECURITY UPDATE: privilege escalation via environment files when + UseLogin is configured + - debian/patches/CVE-2015-8325.patch: ignore PAM environment vars when + UseLogin is enabled in session.c. + - CVE-2015-8325 + * SECURITY UPDATE: fallback from untrusted X11-forwarding to trusted + - debian/patches/CVE-2016-1908-1.patch: use stack memory in + clientloop.c. + - debian/patches/CVE-2016-1908-2.patch: eliminate fallback in + clientloop.c, clientloop.h, mux.c, ssh.c. + - CVE-2016-1908 + * SECURITY UPDATE: shell-command restrictions bypass via crafted X11 + forwarding data + - debian/patches/CVE-2016-3115.patch: sanitise characters destined for + xauth in session.c. + - CVE-2016-3115 + + -- Marc Deslauriers Thu, 05 May 2016 08:43:04 -0400 + openssh (1:5.9p1-5ubuntu1.8) precise-security; urgency=medium * SECURITY UPDATE: information leak and overflow in roaming support diff -Nru openssh-5.9p1/debian/patches/CVE-2015-8325.patch openssh-5.9p1/debian/patches/CVE-2015-8325.patch --- openssh-5.9p1/debian/patches/CVE-2015-8325.patch 1970-01-01 00:00:00.000000000 +0000 +++ openssh-5.9p1/debian/patches/CVE-2015-8325.patch 2016-05-05 12:30:24.000000000 +0000 @@ -0,0 +1,28 @@ +From 85bdcd7c92fe7ff133bbc4e10a65c91810f88755 Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Wed, 13 Apr 2016 10:39:57 +1000 +Subject: ignore PAM environment vars when UseLogin=yes + +If PAM is configured to read user-specified environment variables +and UseLogin=yes in sshd_config, then a hostile local user may +attack /bin/login via LD_PRELOAD or similar environment variables +set via PAM. + +CVE-2015-8325, found by Shayan Sadigh, via Colin Watson +--- + session.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: openssh-5.9p1/session.c +=================================================================== +--- openssh-5.9p1.orig/session.c 2016-05-05 08:30:20.293953183 -0400 ++++ openssh-5.9p1/session.c 2016-05-05 08:30:20.289953137 -0400 +@@ -1292,7 +1292,7 @@ + * Pull in any environment variables that may have + * been set by PAM. + */ +- if (options.use_pam) { ++ if (options.use_pam && !options.use_login) { + char **p; + + p = fetch_pam_child_environment(); diff -Nru openssh-5.9p1/debian/patches/CVE-2016-1908-1.patch openssh-5.9p1/debian/patches/CVE-2016-1908-1.patch --- openssh-5.9p1/debian/patches/CVE-2016-1908-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ openssh-5.9p1/debian/patches/CVE-2016-1908-1.patch 2016-05-05 12:31:00.000000000 +0000 @@ -0,0 +1,53 @@ +Backport of: + +From f98a09cacff7baad8748c9aa217afd155a4d493f Mon Sep 17 00:00:00 2001 +From: "mmcc@openbsd.org" +Date: Tue, 20 Oct 2015 03:36:35 +0000 +Subject: upstream commit + +Replace a function-local allocation with stack memory. + +ok djm@ + +Upstream-ID: c09fbbab637053a2ab9f33ca142b4e20a4c5a17e +--- + clientloop.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +Index: openssh-5.9p1/clientloop.c +=================================================================== +--- openssh-5.9p1.orig/clientloop.c 2016-05-05 08:30:33.966108119 -0400 ++++ openssh-5.9p1/clientloop.c 2016-05-05 08:30:53.730332056 -0400 +@@ -297,11 +297,10 @@ + static char proto[512], data[512]; + FILE *f; + int got_data = 0, generated = 0, do_unlink = 0, i; +- char *xauthdir, *xauthfile; ++ char xauthdir[MAXPATHLEN] = "", xauthfile[MAXPATHLEN] = ""; + struct stat st; + u_int now, x11_timeout_real; + +- xauthdir = xauthfile = NULL; + *_proto = proto; + *_data = data; + proto[0] = data[0] = '\0'; +@@ -326,8 +325,6 @@ + display = xdisplay; + } + if (trusted == 0) { +- xauthdir = xmalloc(MAXPATHLEN); +- xauthfile = xmalloc(MAXPATHLEN); + mktemp_proto(xauthdir, MAXPATHLEN); + /* + * The authentication cookie should briefly outlive +@@ -390,10 +387,6 @@ + unlink(xauthfile); + rmdir(xauthdir); + } +- if (xauthdir) +- xfree(xauthdir); +- if (xauthfile) +- xfree(xauthfile); + + /* + * If we didn't get authentication data, just make up some diff -Nru openssh-5.9p1/debian/patches/CVE-2016-1908-2.patch openssh-5.9p1/debian/patches/CVE-2016-1908-2.patch --- openssh-5.9p1/debian/patches/CVE-2016-1908-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ openssh-5.9p1/debian/patches/CVE-2016-1908-2.patch 2016-05-05 13:24:00.000000000 +0000 @@ -0,0 +1,285 @@ +Backport of: + +From ed4ce82dbfa8a3a3c8ea6fa0db113c71e234416c Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Wed, 13 Jan 2016 23:04:47 +0000 +Subject: upstream commit + +eliminate fallback from untrusted X11 forwarding to trusted + forwarding when the X server disables the SECURITY extension; Reported by + Thomas Hoger; ok deraadt@ + +Upstream-ID: f76195bd2064615a63ef9674a0e4096b0713f938 +--- + clientloop.c | 114 ++++++++++++++++++++++++++++++++++++----------------------- + clientloop.h | 4 +-- + mux.c | 22 ++++++------ + ssh.c | 23 +++++------- + 4 files changed, 93 insertions(+), 70 deletions(-) + +Index: openssh-5.9p1/clientloop.c +=================================================================== +--- openssh-5.9p1.orig/clientloop.c 2016-05-05 08:31:11.882537689 -0400 ++++ openssh-5.9p1/clientloop.c 2016-05-05 08:39:14.467991784 -0400 +@@ -287,31 +287,33 @@ + + #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" + #define X11_TIMEOUT_SLACK 60 +-void ++int + client_x11_get_proto(const char *display, const char *xauth_path, + u_int trusted, u_int timeout, char **_proto, char **_data) + { +- char cmd[1024]; +- char line[512]; +- char xdisplay[512]; ++ char cmd[1024], line[512], xdisplay[512]; ++ char xauthfile[MAXPATHLEN], xauthdir[MAXPATHLEN]; + static char proto[512], data[512]; + FILE *f; +- int got_data = 0, generated = 0, do_unlink = 0, i; +- char xauthdir[MAXPATHLEN] = "", xauthfile[MAXPATHLEN] = ""; ++ int got_data = 0, generated = 0, do_unlink = 0, i, r; + struct stat st; + u_int now, x11_timeout_real; + + *_proto = proto; + *_data = data; +- proto[0] = data[0] = '\0'; ++ proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0'; + +- if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { ++ if (display == NULL) { ++ debug("x11_get_proto: DISPLAY not set"); ++ return -1; ++ } ++ ++ if (xauth_path != NULL && stat(xauth_path, &st) == -1) { + debug("No xauth program."); +- } else { +- if (display == NULL) { +- debug("x11_get_proto: DISPLAY not set"); +- return; +- } ++ xauth_path = NULL; ++ } ++ ++ if (xauth_path != NULL) { + /* + * Handle FamilyLocal case where $DISPLAY does + * not match an authorization entry. For this we +@@ -320,43 +322,60 @@ + * is not perfect. + */ + if (strncmp(display, "localhost:", 10) == 0) { +- snprintf(xdisplay, sizeof(xdisplay), "unix:%s", +- display + 10); ++ if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s", ++ display + 10)) < 0 || ++ (size_t)r >= sizeof(xdisplay)) { ++ error("%s: display name too long", __func__); ++ return -1; ++ } + display = xdisplay; + } + if (trusted == 0) { +- mktemp_proto(xauthdir, MAXPATHLEN); + /* ++ * Generate an untrusted X11 auth cookie. ++ * + * The authentication cookie should briefly outlive + * ssh's willingness to forward X11 connections to + * avoid nasty fail-open behaviour in the X server. + */ ++ mktemp_proto(xauthdir, sizeof(xauthdir)); ++ if (mkdtemp(xauthdir) == NULL) { ++ error("%s: mkdtemp: %s", ++ __func__, strerror(errno)); ++ return -1; ++ } ++ do_unlink = 1; ++ if ((r = snprintf(xauthfile, sizeof(xauthfile), ++ "%s/xauthfile", xauthdir)) < 0 || ++ (size_t)r >= sizeof(xauthfile)) { ++ error("%s: xauthfile path too long", __func__); ++ unlink(xauthfile); ++ rmdir(xauthdir); ++ return -1; ++ } ++ + if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK) + x11_timeout_real = UINT_MAX; + else + x11_timeout_real = timeout + X11_TIMEOUT_SLACK; +- if (mkdtemp(xauthdir) != NULL) { +- do_unlink = 1; +- snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", +- xauthdir); +- snprintf(cmd, sizeof(cmd), +- "%s -f %s generate %s " SSH_X11_PROTO +- " untrusted timeout %u 2>" _PATH_DEVNULL, +- xauth_path, xauthfile, display, +- x11_timeout_real); +- debug2("x11_get_proto: %s", cmd); +- if (x11_refuse_time == 0) { +- now = time(NULL) + 1; +- if (UINT_MAX - timeout < now) +- x11_refuse_time = UINT_MAX; +- else +- x11_refuse_time = now + timeout; +- channel_set_x11_refuse_time( +- x11_refuse_time); +- } +- if (system(cmd) == 0) +- generated = 1; ++ if ((r = snprintf(cmd, sizeof(cmd), ++ "%s -f %s generate %s " SSH_X11_PROTO ++ " untrusted timeout %u 2>" _PATH_DEVNULL, ++ xauth_path, xauthfile, display, ++ x11_timeout_real)) < 0 || ++ (size_t)r >= sizeof(cmd)) ++ fatal("%s: cmd too long", __func__); ++ debug2("%s: %s", __func__, cmd); ++ if (x11_refuse_time == 0) { ++ now = time(NULL) + 1; ++ if (UINT_MAX - timeout < now) ++ x11_refuse_time = UINT_MAX; ++ else ++ x11_refuse_time = now + timeout; ++ channel_set_x11_refuse_time(x11_refuse_time); + } ++ if (system(cmd) == 0) ++ generated = 1; + } + + /* +@@ -378,9 +397,7 @@ + got_data = 1; + if (f) + pclose(f); +- } else +- error("Warning: untrusted X11 forwarding setup failed: " +- "xauth key data not generated"); ++ } + } + + if (do_unlink) { +@@ -388,6 +405,13 @@ + rmdir(xauthdir); + } + ++ /* Don't fall back to fake X11 data for untrusted forwarding */ ++ if (!trusted && !got_data) { ++ error("Warning: untrusted X11 forwarding setup failed: " ++ "xauth key data not generated"); ++ return -1; ++ } ++ + /* + * If we didn't get authentication data, just make up some + * data. The forwarding code will check the validity of the +@@ -410,6 +434,8 @@ + rnd >>= 8; + } + } ++ ++ return 0; + } + + /* +Index: openssh-5.9p1/clientloop.h +=================================================================== +--- openssh-5.9p1.orig/clientloop.h 2016-05-05 08:31:11.882537689 -0400 ++++ openssh-5.9p1/clientloop.h 2016-05-05 08:31:11.874537598 -0400 +@@ -39,7 +39,7 @@ + + /* Client side main loop for the interactive session. */ + int client_loop(int, int, int); +-void client_x11_get_proto(const char *, const char *, u_int, u_int, ++int client_x11_get_proto(const char *, const char *, u_int, u_int, + char **, char **); + void client_global_request_reply_fwd(int, u_int32_t, void *); + void client_session2_setup(int, int, int, const char *, struct termios *, +Index: openssh-5.9p1/mux.c +=================================================================== +--- openssh-5.9p1.orig/mux.c 2016-05-05 08:31:11.882537689 -0400 ++++ openssh-5.9p1/mux.c 2016-05-05 08:31:11.874537598 -0400 +@@ -1208,16 +1208,18 @@ + char *proto, *data; + + /* Get reasonable local authentication information. */ +- client_x11_get_proto(display, options.xauth_location, ++ if (client_x11_get_proto(display, options.xauth_location, + options.forward_x11_trusted, options.forward_x11_timeout, +- &proto, &data); +- /* Request forwarding with authentication spoofing. */ +- debug("Requesting X11 forwarding with authentication " +- "spoofing."); +- x11_request_forwarding_with_spoofing(id, display, proto, +- data, 1); +- client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); +- /* XXX exit_on_forward_failure */ ++ &proto, &data) == 0) { ++ /* Request forwarding with authentication spoofing. */ ++ debug("Requesting X11 forwarding with authentication " ++ "spoofing."); ++ x11_request_forwarding_with_spoofing(id, display, proto, ++ data, 1); ++ /* XXX exit_on_forward_failure */ ++ client_expect_confirm(id, "X11 forwarding", ++ CONFIRM_WARN); ++ } + } + + if (cctx->want_agent_fwd && options.forward_agent) { +Index: openssh-5.9p1/ssh.c +=================================================================== +--- openssh-5.9p1.orig/ssh.c 2016-05-05 08:31:11.882537689 -0400 ++++ openssh-5.9p1/ssh.c 2016-05-05 08:39:50.748400866 -0400 +@@ -1161,6 +1161,7 @@ + struct winsize ws; + char *cp; + const char *display; ++ char *proto = NULL, *data = NULL; + + /* Enable compression if requested. */ + if (options.compression) { +@@ -1229,13 +1230,9 @@ + } + /* Request X11 forwarding if enabled and DISPLAY is set. */ + display = getenv("DISPLAY"); +- if (options.forward_x11 && display != NULL) { +- char *proto, *data; +- /* Get reasonable local authentication information. */ +- client_x11_get_proto(display, options.xauth_location, +- options.forward_x11_trusted, +- options.forward_x11_timeout, +- &proto, &data); ++ if (options.forward_x11 && client_x11_get_proto(display, ++ options.xauth_location, options.forward_x11_trusted, ++ options.forward_x11_timeout, &proto, &data) == 0) { + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication " + "spoofing."); +@@ -1324,17 +1321,15 @@ + extern char **environ; + const char *display; + int interactive = tty_flag; ++ char *proto = NULL, *data = NULL; + + if (!success) + return; /* No need for error message, channels code sens one */ + + display = getenv("DISPLAY"); +- if (options.forward_x11 && display != NULL) { +- char *proto, *data; +- /* Get reasonable local authentication information. */ +- client_x11_get_proto(display, options.xauth_location, +- options.forward_x11_trusted, +- options.forward_x11_timeout, &proto, &data); ++ if (options.forward_x11 && client_x11_get_proto(display, ++ options.xauth_location, options.forward_x11_trusted, ++ options.forward_x11_timeout, &proto, &data) == 0) { + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication " + "spoofing."); diff -Nru openssh-5.9p1/debian/patches/CVE-2016-3115.patch openssh-5.9p1/debian/patches/CVE-2016-3115.patch --- openssh-5.9p1/debian/patches/CVE-2016-3115.patch 1970-01-01 00:00:00.000000000 +0000 +++ openssh-5.9p1/debian/patches/CVE-2016-3115.patch 2016-05-05 12:42:59.000000000 +0000 @@ -0,0 +1,76 @@ +Backport of: + +From 9d47b8d3f50c3a6282896df8274147e3b9a38c56 Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Thu, 10 Mar 2016 05:03:39 +1100 +Subject: sanitise characters destined for xauth(1) + +reported by github.com/tintinweb +--- + session.c | 32 ++++++++++++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +Index: openssh-5.9p1/session.c +=================================================================== +--- openssh-5.9p1.orig/session.c 2016-05-05 08:41:46.809708670 -0400 ++++ openssh-5.9p1/session.c 2016-05-05 08:41:46.805708625 -0400 +@@ -46,6 +46,7 @@ + + #include + ++#include + #include + #include + #include +@@ -287,6 +288,21 @@ + do_cleanup(authctxt); + } + ++/* Check untrusted xauth strings for metacharacters */ ++static int ++xauth_valid_string(const char *s) ++{ ++ size_t i; ++ ++ for (i = 0; s[i] != '\0'; i++) { ++ if (!isalnum((u_char)s[i]) && ++ s[i] != '.' && s[i] != ':' && s[i] != '/' && ++ s[i] != '-' && s[i] != '_') ++ return 0; ++ } ++ return 1; ++} ++ + /* + * Prepares for an interactive session. This is called after the user has + * been successfully authenticated. During this message exchange, pseudo +@@ -360,7 +376,13 @@ + s->screen = 0; + } + packet_check_eom(); +- success = session_setup_x11fwd(s); ++ if (xauth_valid_string(s->auth_proto) && ++ xauth_valid_string(s->auth_data)) ++ success = session_setup_x11fwd(s); ++ else { ++ success = 0; ++ error("Invalid X11 forwarding data"); ++ } + if (!success) { + xfree(s->auth_proto); + xfree(s->auth_data); +@@ -2144,7 +2166,13 @@ + s->screen = packet_get_int(); + packet_check_eom(); + +- success = session_setup_x11fwd(s); ++ if (xauth_valid_string(s->auth_proto) && ++ xauth_valid_string(s->auth_data)) ++ success = session_setup_x11fwd(s); ++ else { ++ success = 0; ++ error("Invalid X11 forwarding data"); ++ } + if (!success) { + xfree(s->auth_proto); + xfree(s->auth_data); diff -Nru openssh-5.9p1/debian/patches/series openssh-5.9p1/debian/patches/series --- openssh-5.9p1/debian/patches/series 2016-01-13 15:48:47.000000000 +0000 +++ openssh-5.9p1/debian/patches/series 2016-05-05 12:41:45.000000000 +0000 @@ -56,3 +56,7 @@ CVE-2015-5352.patch CVE-2015-5600-2.patch CVE-2016-077x.patch +CVE-2015-8325.patch +CVE-2016-1908-1.patch +CVE-2016-1908-2.patch +CVE-2016-3115.patch