[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