aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon L. B. Nielsen <simon@FreeBSD.org>2006-09-30 19:58:07 +0000
committerSimon L. B. Nielsen <simon@FreeBSD.org>2006-09-30 19:58:07 +0000
commitc86ddc159169e05b81ff2b0c5b81e698a4ecf6c8 (patch)
tree09d60eccd356ab73faaeaf18e3064cafe09fbbc1
parent03de91198524923dce0f9f58d5af77235f340e5e (diff)
downloadsrc-c86ddc159169e05b81ff2b0c5b81e698a4ecf6c8.tar.gz
src-c86ddc159169e05b81ff2b0c5b81e698a4ecf6c8.zip
Correct multiple vulnerabilities in OpenSSH.
Security: FreeBSD-SA-06:22.openssh Approved by: so (simon)
Notes
Notes: svn path=/releng/4.11/; revision=162896
-rw-r--r--UPDATING3
-rw-r--r--crypto/openssh/deattack.c24
-rw-r--r--crypto/openssh/deattack.h1
-rw-r--r--crypto/openssh/defines.h5
-rw-r--r--crypto/openssh/log.c14
-rw-r--r--crypto/openssh/log.h1
-rw-r--r--crypto/openssh/packet.c13
-rw-r--r--crypto/openssh/ssh_config2
-rw-r--r--crypto/openssh/ssh_config.52
-rw-r--r--crypto/openssh/sshd.c2
-rw-r--r--crypto/openssh/sshd_config2
-rw-r--r--crypto/openssh/sshd_config.52
-rw-r--r--crypto/openssh/version.h2
-rw-r--r--sys/conf/newvers.sh2
14 files changed, 63 insertions, 12 deletions
diff --git a/UPDATING b/UPDATING
index 9d8e698a281f..2bd7cbdafc5a 100644
--- a/UPDATING
+++ b/UPDATING
@@ -17,6 +17,9 @@ minimal number of processes, if possible, for that patch. For those
updates that don't have an advisory, or to be safe, you can do a full
build and install as described in the COMMON ITEMS section.
+20060930: p25 FreeBSD-SA-06:22.openssh
+ Correct multiple vulnerabilities in sshd(8).
+
20060929: p24 FreeBSD-SA-06:23.openssl
Correct problem in the 2006-09-28 patch concerning the handling of
excessively large DH moduli.
diff --git a/crypto/openssh/deattack.c b/crypto/openssh/deattack.c
index 7bf2749fceb3..d29f5892f731 100644
--- a/crypto/openssh/deattack.c
+++ b/crypto/openssh/deattack.c
@@ -27,6 +27,24 @@ RCSID("$OpenBSD: deattack.c,v 1.18 2002/03/04 17:27:39 stevesk Exp $");
#include "xmalloc.h"
#include "deattack.h"
+/*
+ * CRC attack detection has a worst-case behaviour that is O(N^3) over
+ * the number of identical blocks in a packet. This behaviour can be
+ * exploited to create a limited denial of service attack.
+ *
+ * However, because we are dealing with encrypted data, identical
+ * blocks should only occur every 2^35 maximally-sized packets or so.
+ * Consequently, we can detect this DoS by looking for identical blocks
+ * in a packet.
+ *
+ * The parameter below determines how many identical blocks we will
+ * accept in a single packet, trading off between attack detection and
+ * likelihood of terminating a legitimate connection. A value of 32
+ * corresponds to an average of 2^40 messages before an attack is
+ * misdetected
+ */
+#define MAX_IDENTICAL 32
+
/* SSH Constants */
#define SSH_MAXBLOCKS (32 * 1024)
#define SSH_BLOCKSIZE (8)
@@ -87,7 +105,7 @@ detect_attack(u_char *buf, u_int32_t len, u_char *IV)
static u_int16_t *h = (u_int16_t *) NULL;
static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
u_int32_t i, j;
- u_int32_t l;
+ u_int32_t l, same;
u_char *c;
u_char *d;
@@ -133,7 +151,7 @@ detect_attack(u_char *buf, u_int32_t len, u_char *IV)
if (IV)
h[HASH(IV) & (n - 1)] = HASH_IV;
- for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
+ for (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
i = (i + 1) & (n - 1)) {
if (h[i] == HASH_IV) {
@@ -144,6 +162,8 @@ detect_attack(u_char *buf, u_int32_t len, u_char *IV)
break;
}
} else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) {
+ if (++same > MAX_IDENTICAL)
+ return (DEATTACK_DOS_DETECTED);
if (check_crc(c, buf, len, IV))
return (DEATTACK_DETECTED);
else
diff --git a/crypto/openssh/deattack.h b/crypto/openssh/deattack.h
index ddccdea50594..cd3d7aa3b5a7 100644
--- a/crypto/openssh/deattack.h
+++ b/crypto/openssh/deattack.h
@@ -25,6 +25,7 @@
/* Return codes */
#define DEATTACK_OK 0
#define DEATTACK_DETECTED 1
+#define DEATTACK_DOS_DETECTED 2
int detect_attack(u_char *, u_int32_t, u_char[8]);
#endif
diff --git a/crypto/openssh/defines.h b/crypto/openssh/defines.h
index ab19a077cc08..bca0c14f3e7f 100644
--- a/crypto/openssh/defines.h
+++ b/crypto/openssh/defines.h
@@ -450,6 +450,11 @@ struct winsize {
# undef HAVE_GAI_STRERROR
#endif
+#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \
+ defined(SYSLOG_R_SAFE_IN_SIGHAND)
+# define DO_LOG_SAFE_IN_SIGHAND
+#endif
+
#if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY)
# define memmove(s1, s2, n) bcopy((s2), (s1), (n))
#endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */
diff --git a/crypto/openssh/log.c b/crypto/openssh/log.c
index 96626d7d4dab..c0398267abbd 100644
--- a/crypto/openssh/log.c
+++ b/crypto/openssh/log.c
@@ -124,6 +124,20 @@ error(const char *fmt,...)
va_end(args);
}
+void
+sigdie(const char *fmt,...)
+{
+ va_list args;
+
+#ifdef DO_LOG_SAFE_IN_SIGHAND
+ va_start(args, fmt);
+ do_log(SYSLOG_LEVEL_FATAL, fmt, args);
+ va_end(args);
+#endif
+ _exit(1);
+}
+
+
/* Log this message (information that usually should go to the log). */
void
diff --git a/crypto/openssh/log.h b/crypto/openssh/log.h
index 917fafa69179..15a09031ce60 100644
--- a/crypto/openssh/log.h
+++ b/crypto/openssh/log.h
@@ -55,6 +55,7 @@ LogLevel log_level_number(char *);
void fatal(const char *, ...) __attribute__((format(printf, 1, 2)));
void error(const char *, ...) __attribute__((format(printf, 1, 2)));
+void sigdie(const char *, ...) __attribute__((format(printf, 1, 2)));
void log(const char *, ...) __attribute__((format(printf, 1, 2)));
void verbose(const char *, ...) __attribute__((format(printf, 1, 2)));
void debug(const char *, ...) __attribute__((format(printf, 1, 2)));
diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c
index bd347ef0f4ff..bbe43de71bc1 100644
--- a/crypto/openssh/packet.c
+++ b/crypto/openssh/packet.c
@@ -857,9 +857,16 @@ packet_read_poll1(void)
* (C)1998 CORE-SDI, Buenos Aires Argentina
* Ariel Futoransky(futo@core-sdi.com)
*/
- if (!receive_context.plaintext &&
- detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED)
- packet_disconnect("crc32 compensation attack: network attack detected");
+ if (!receive_context.plaintext) {
+ switch (detect_attack(buffer_ptr(&input), padded_len, NULL)) {
+ case DEATTACK_DETECTED:
+ packet_disconnect("crc32 compensation attack: "
+ "network attack detected");
+ case DEATTACK_DOS_DETECTED:
+ packet_disconnect("deattack denial of "
+ "service detected");
+ }
+ }
/* Decrypt data to incoming_packet. */
buffer_clear(&incoming_packet);
diff --git a/crypto/openssh/ssh_config b/crypto/openssh/ssh_config
index e3f82cfd0a9f..2d6af7885007 100644
--- a/crypto/openssh/ssh_config
+++ b/crypto/openssh/ssh_config
@@ -35,4 +35,4 @@
# Cipher 3des
# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
# EscapeChar ~
-# VersionAddendum FreeBSD-20030924
+# VersionAddendum FreeBSD-20060930
diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5
index b1b6eec4a7a8..efd3c7920801 100644
--- a/crypto/openssh/ssh_config.5
+++ b/crypto/openssh/ssh_config.5
@@ -616,7 +616,7 @@ host key database instead of
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
-.Dq FreeBSD-20030924 .
+.Dq FreeBSD-20060930 .
.It Cm XAuthLocation
Specifies the full pathname of the
.Xr xauth 1
diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
index cb25d36bf3f1..2464b69d93a8 100644
--- a/crypto/openssh/sshd.c
+++ b/crypto/openssh/sshd.c
@@ -309,7 +309,7 @@ grace_alarm_handler(int sig)
/* XXX no idea how fix this signal handler */
/* Log error and exit. */
- fatal("Timeout before authentication for %s", get_remote_ipaddr());
+ sigdie("Timeout before authentication for %s", get_remote_ipaddr());
}
/*
diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config
index 56fb52c90f32..05fdbbf73532 100644
--- a/crypto/openssh/sshd_config
+++ b/crypto/openssh/sshd_config
@@ -14,7 +14,7 @@
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
# FreeBSD has a few additional options.
-#VersionAddendum FreeBSD-20030924
+#VersionAddendum FreeBSD-20060930
#Port 22
#Protocol 2,1
diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5
index 40c0c31274b1..4411a9bd66ac 100644
--- a/crypto/openssh/sshd_config.5
+++ b/crypto/openssh/sshd_config.5
@@ -647,7 +647,7 @@ The default is
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
-.Dq FreeBSD-20030924 .
+.Dq FreeBSD-20060930 .
.It Cm X11DisplayOffset
Specifies the first display number available for
.Nm sshd Ns 's
diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h
index ef99721a0eb0..6b5d9678c607 100644
--- a/crypto/openssh/version.h
+++ b/crypto/openssh/version.h
@@ -5,7 +5,7 @@
#define SSH_VERSION (ssh_version_get())
#define SSH_VERSION_BASE "OpenSSH_3.5p1"
-#define SSH_VERSION_ADDENDUM "FreeBSD-20030924"
+#define SSH_VERSION_ADDENDUM "FreeBSD-20060930"
const char *ssh_version_get(void);
void ssh_version_set_addendum(const char *add);
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 611c435c38dd..3be26cc90acf 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -36,7 +36,7 @@
TYPE="FreeBSD"
REVISION="4.11"
-BRANCH="RELEASE-p24"
+BRANCH="RELEASE-p25"
RELEASE="${REVISION}-${BRANCH}"
VERSION="${TYPE} ${RELEASE}"