summaryrefslogtreecommitdiff
blob: 03dd1d82fd6f96420e0105c29aaba96627d1ac98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
commit a24db7f9864240a4ebb236a6615ec649138fef0e
Author: TJ Saunders <tj@castaglia.org>
Date:   Sat Nov 28 17:08:03 2015 -0800

    Bug#4210 - Avoid unbounded SFTP extension key/values.

diff --git a/contrib/mod_sftp/fxp.c b/contrib/mod_sftp/fxp.c
index 5d9ae17..03c7eb5 100644
--- a/contrib/mod_sftp/fxp.c
+++ b/contrib/mod_sftp/fxp.c
@@ -241,6 +241,9 @@ struct fxp_extpair {
   unsigned char *ext_data;
 };
 
+/* Maximum length of SFTP extension name, AND of the extension value. */
+#define SFTP_EXT_MAX_LEN			1024
+
 static pool *fxp_pool = NULL;
 static int fxp_use_gmt = TRUE;
 
@@ -1240,6 +1243,14 @@ static struct fxp_extpair *fxp_msg_read_extpair(pool *p, unsigned char **buf,
     SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION, NULL);
   }
 
+  if (namelen > SFTP_EXT_MAX_LEN) {
+    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+      "received too-long SFTP extension name (%lu > max %lu), ignoring",
+      (unsigned long) namelen, (unsigned long) SFTP_EXT_MAX_LEN);
+    errno = EINVAL;
+    return NULL;
+  }
+
   name = palloc(p, namelen + 1);
   memcpy(name, *buf, namelen);
   (*buf) += namelen;
@@ -1248,6 +1259,14 @@ static struct fxp_extpair *fxp_msg_read_extpair(pool *p, unsigned char **buf,
 
   datalen = sftp_msg_read_int(p, buf, buflen);
   if (datalen > 0) {
+    if (datalen > SFTP_EXT_MAX_LEN) {
+      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+        "received too-long SFTP extension '%s' data (%lu > max %lu), ignoring",
+        name, (unsigned long) datalen, (unsigned long) SFTP_EXT_MAX_LEN);
+      errno = EINVAL;
+      return NULL;
+    }
+
     data = sftp_msg_read_data(p, buf, buflen, datalen);
 
   } else {
@@ -2210,11 +2229,13 @@ static struct stat *fxp_attrs_read(struct fxp_packet *fxp, unsigned char **buf,
         struct fxp_extpair *ext;
 
         ext = fxp_msg_read_extpair(fxp->pool, buf, buflen);
-        pr_trace_msg(trace_channel, 15,
-          "protocol version %lu: read EXTENDED attribute: "
-          "extension '%s' (%lu bytes of data)",
-          (unsigned long) fxp_session->client_version, ext->ext_name,
-          (unsigned long) ext->ext_datalen);
+        if (ext != NULL) {
+          pr_trace_msg(trace_channel, 15,
+            "protocol version %lu: read EXTENDED attribute: "
+            "extension '%s' (%lu bytes of data)",
+            (unsigned long) fxp_session->client_version, ext->ext_name,
+            (unsigned long) ext->ext_datalen);
+        }
       }
     }