[SCM] proftpd-dfsg branch, master, updated. debian/1.3.3a-6-23-g9ed0581
Francesco Paolo Lovergine
frankie at debian.org
Thu Mar 3 23:26:17 UTC 2011
The following commit has been merged in the master branch:
commit 9ed0581e1a06610eaeced9040874cab984498d2a
Author: Francesco Paolo Lovergine <frankie at debian.org>
Date: Fri Mar 4 00:25:20 2011 +0100
Fixed CVE-2011-1137 and set to high priority.
diff --git a/debian/changelog b/debian/changelog
index 39aea8c..d2c117b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-proftpd-dfsg (1.3.3d-4) unstable; urgency=low
+proftpd-dfsg (1.3.3d-4) unstable; urgency=high
* Fixed previous changelog.
* Now proftpd.conf includes /etc/proftpd/conf.d contents to allow custom
@@ -11,8 +11,10 @@ proftpd-dfsg (1.3.3d-4) unstable; urgency=low
* Now configuration file name can be overriden at run-time.
(closes: #613527)
* Now uses Breaks instead of Conflicts against pre-squeeze proftpd package.
+ * [SECURITY,PATCH] CVE-2011-1137: mod_sftp behaves badly when receiving
+ badly formed SSH messages.
- -- Francesco Paolo Lovergine <frankie at debian.org> Sat, 19 Feb 2011 15:33:36 +0100
+ -- Francesco Paolo Lovergine <frankie at debian.org> Fri, 04 Mar 2011 00:23:05 +0100
proftpd-dfsg (1.3.3d-3) unstable; urgency=low
diff --git a/debian/patches/CVE-2011-1137 b/debian/patches/CVE-2011-1137
new file mode 100644
index 0000000..23bb029
--- /dev/null
+++ b/debian/patches/CVE-2011-1137
@@ -0,0 +1,150 @@
+Index: proftpd-dfsg/contrib/mod_sftp/mod_sftp.c
+===================================================================
+--- proftpd-dfsg.orig/contrib/mod_sftp/mod_sftp.c 2011-02-10 20:32:57.000000000 +0100
++++ proftpd-dfsg/contrib/mod_sftp/mod_sftp.c 2011-03-04 00:22:37.000000000 +0100
+@@ -83,12 +83,12 @@
+ memset(buf, '\0', sizeof(buf));
+
+ for (i = 0; i < sizeof(buf) - 1; i++) {
+- res = sftp_ssh2_packet_sock_read(conn->rfd, &buf[i], 1);
++ res = sftp_ssh2_packet_sock_read(conn->rfd, &buf[i], 1, 0);
+ while (res <= 0) {
+ if (errno == EINTR) {
+ pr_signals_handle();
+
+- res = sftp_ssh2_packet_sock_read(conn->rfd, &buf[i], 1);
++ res = sftp_ssh2_packet_sock_read(conn->rfd, &buf[i], 1, 0);
+ continue;
+ }
+
+Index: proftpd-dfsg/contrib/mod_sftp/packet.c
+===================================================================
+--- proftpd-dfsg.orig/contrib/mod_sftp/packet.c 2011-02-10 20:32:57.000000000 +0100
++++ proftpd-dfsg/contrib/mod_sftp/packet.c 2011-03-04 00:22:37.000000000 +0100
+@@ -46,6 +46,12 @@
+ static uint32_t packet_client_seqno = 0;
+ static uint32_t packet_server_seqno = 0;
+
++/* Maximum length of the payload data of an SSH2 packet we're willing to
++ * accept. Any packets reporting a payload length longer than this will be
++ * ignored/dropped.
++ */
++#define SFTP_PACKET_MAX_PAYLOAD_LEN (256 * 1024)
++
+ /* RFC4344 recommends 2^31 for the client packet sequence number at which
+ * we should request a rekey, and 2^32 for the server packet sequence number.
+ * Since we're using uin32_t, though, it isn't a big enough data type for those
+@@ -138,7 +144,8 @@
+ * It is the caller's responsibility to ensure that buf is large enough to
+ * hold reqlen bytes.
+ */
+-int sftp_ssh2_packet_sock_read(int sockfd, void *buf, size_t reqlen) {
++int sftp_ssh2_packet_sock_read(int sockfd, void *buf, size_t reqlen,
++ int flags) {
+ void *ptr;
+ size_t remainlen;
+
+@@ -213,6 +220,13 @@
+ if (res == remainlen)
+ break;
+
++ if (flags & SFTP_PACKET_READ_FL_PESSIMISTIC) {
++ pr_trace_msg(trace_channel, 20, "read %lu bytes, expected %lu bytes; "
++ "pessimistically returning", (unsigned long) res,
++ (unsigned long) remainlen);
++ break;
++ }
++
+ pr_trace_msg(trace_channel, 20, "read %lu bytes, expected %lu bytes; "
+ "reading more", (unsigned long) res, (unsigned long) remainlen);
+ ptr = ((char *) ptr + res);
+@@ -363,7 +377,12 @@
+ (unsigned long) buflen);
+
+ if (buflen > 0) {
+- sftp_ssh2_packet_sock_read(sockfd, buf, buflen);
++ int flags = SFTP_PACKET_READ_FL_PESSIMISTIC;
++
++ /* We don't necessary want to wait for the entire random amount of data
++ * to be read in.
++ */
++ sftp_ssh2_packet_sock_read(sockfd, buf, buflen, flags);
+ }
+
+ return;
+@@ -383,7 +402,7 @@
+ * how many more bytes there are in the packet.
+ */
+
+- res = sftp_ssh2_packet_sock_read(sockfd, buf, blocksz);
++ res = sftp_ssh2_packet_sock_read(sockfd, buf, blocksz, 0);
+ if (res < 0)
+ return res;
+
+@@ -441,8 +460,26 @@
+ if (payload_len + padding_len == 0)
+ return 0;
+
+- if (payload_len > 0)
++ if (payload_len > 0) {
++ /* We don't want to reject the packet outright yet; but we can ignore
++ * the payload data we're going to read in. This packet will fail
++ * eventually anyway.
++ */
++ if (payload_len > SFTP_PACKET_MAX_PAYLOAD_LEN) {
++ pr_trace_msg(trace_channel, 20,
++ "payload len (%lu bytes) exceeds max payload len (%lu), "
++ "ignoring payload", (unsigned long) payload_len,
++ (unsigned long) SFTP_PACKET_MAX_PAYLOAD_LEN);
++
++ pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
++ "client sent buggy/malicious packet payload length, ignoring");
++
++ errno = EPERM;
++ return -1;
++ }
++
+ pkt->payload = pcalloc(pkt->pool, payload_len);
++ }
+
+ /* If there's data in the buffer we received, it's probably already part
+ * of the payload, unencrypted. That will leave the remaining payload
+@@ -503,7 +540,7 @@
+ return -1;
+ }
+
+- res = sftp_ssh2_packet_sock_read(sockfd, buf + *offset, data_len);
++ res = sftp_ssh2_packet_sock_read(sockfd, buf + *offset, data_len, 0);
+ if (res < 0) {
+ return res;
+ }
+@@ -531,7 +568,7 @@
+ if (mac_len == 0)
+ return 0;
+
+- res = sftp_ssh2_packet_sock_read(sockfd, buf, mac_len);
++ res = sftp_ssh2_packet_sock_read(sockfd, buf, mac_len, 0);
+ if (res < 0)
+ return res;
+
+Index: proftpd-dfsg/contrib/mod_sftp/packet.h
+===================================================================
+--- proftpd-dfsg.orig/contrib/mod_sftp/packet.h 2011-02-10 20:32:57.000000000 +0100
++++ proftpd-dfsg/contrib/mod_sftp/packet.h 2011-03-04 00:22:37.000000000 +0100
+@@ -78,7 +78,15 @@
+ int sftp_ssh2_packet_get_last_sent(time_t *);
+
+ int sftp_ssh2_packet_read(int, struct ssh2_packet *);
+-int sftp_ssh2_packet_sock_read(int, void *, size_t);
++int sftp_ssh2_packet_sock_read(int, void *, size_t, int);
++
++/* This sftp_ssh2_packet_sock_read() flag is used to tell the function to
++ * read in as many of the requested length of data as it can, but to NOT
++ * keep polling until that length has been acquired (i.e. to read the
++ * requested length pessimistically, assuming that it will not all appear).
++ */
++#define SFTP_PACKET_READ_FL_PESSIMISTIC 0x001
++
+ int sftp_ssh2_packet_write(int, struct ssh2_packet *);
+
+ int sftp_ssh2_packet_handle(void);
diff --git a/debian/patches/series b/debian/patches/series
index 9a513d2..9f8e3e5 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -11,3 +11,4 @@ odbc
mod_vroot
prxs
silent
+CVE-2011-1137
--
ProFTPD core package
More information about the Pkg-proftpd-maintainers
mailing list