commit a24db7f9864240a4ebb236a6615ec649138fef0e Author: TJ Saunders 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); + } } }