bagder: curl-www/CVE-2009-0037 curl-7.15.3-CVE-2009-0037.patch, NONE, 1.1 curl-7.17.0-CVE-2009-0037.patch, NONE, 1.1
[email protected] Wed, 11 Mar 2009 08:44:05 +0000
| Newsgroups | gmane.comp.web.curl.www.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/curl/curl-www/CVE-2009-0037
In directory labb:/tmp/cvs-serv18698
Added Files:
curl-7.15.3-CVE-2009-0037.patch
curl-7.17.0-CVE-2009-0037.patch
Log Message:
Thanks to Elliot Peele for the 7.15.3 and 7.17.0 patches
--- NEW FILE: curl-7.15.3-CVE-2009-0037.patch ---
diff -r deb9cb6b2a00 docs/libcurl/curl_easy_setopt.3
--- a/docs/libcurl/curl_easy_setopt.3 Wed Mar 04 16:34:52 2009 -0500
+++ b/docs/libcurl/curl_easy_setopt.3 Wed Mar 04 17:25:09 2009 -0500
@@ -297,6 +297,26 @@
\fICURLOPT_URL\fP is the only option that must be set before
\fIcurl_easy_perform(3)\fP is called.
+
+\fICURLOPT_PROTOCOLS\fP can be used to limit what protocols libcurl will use
+for this transfer, independent of what libcurl has been compiled to
+support. That may be useful if you accept the URL from an external source and
+want to limit the accessibility.
+.IP CURLOPT_PROTOCOLS
+Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
+limits what protocols libcurl may use in the transfer. This allows you to have
+a libcurl built to support a wide range of protocols but still limit specific
+transfers to only be allowed to use a subset of them. By default libcurl will
+accept all protocols it supports. See also
+\fICURLOPT_REDIR_PROTOCOLS\fP. (Added in 7.19.4)
+.IP CURLOPT_REDIR_PROTOCOLS
+Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
+limits what protocols libcurl may use in a transfer that it follows to in a
+redirect when \fICURLOPT_FOLLOWLOCATION\fP is enabled. This allows you to
+limit specific transfers to only be allowed to use a subset of protocols in
+redirections. By default libcurl will allow all protocols except for FILE and
+SCP. This is a difference compared to pre-7.19.4 versions which
+unconditionally would follow to all protocols supported. (Added in 7.19.4)
.IP CURLOPT_PROXY
Set HTTP proxy to use. The parameter should be a char * to a zero terminated
string holding the host name or dotted IP address. To specify port number in
@@ -525,6 +545,10 @@
and follow new Location: headers all the way until no more such headers are
returned. \fICURLOPT_MAXREDIRS\fP can be used to limit the number of redirects
libcurl will follow.
+
+NOTE: since 7.19.4, libcurl can limit to what protocols it will automatically
+follow. The accepted protocols are set with \fICURLOPT_REDIR_PROTOCOLS\fP and
+it excludes the FILE protocol by default.
.IP CURLOPT_UNRESTRICTED_AUTH
A non-zero parameter tells the library it can continue to send authentication
(user+password) when following locations, even when hostname changed. This
diff -r deb9cb6b2a00 include/curl/curl.h
--- a/include/curl/curl.h Wed Mar 04 16:34:52 2009 -0500
+++ b/include/curl/curl.h Wed Mar 04 17:25:09 2009 -0500
@@ -390,6 +390,19 @@
CURLFTPMETHOD_LAST /* not an option, never use */
} curl_ftpmethod;
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP (1<<0)
+#define CURLPROTO_HTTPS (1<<1)
+#define CURLPROTO_FTP (1<<2)
+#define CURLPROTO_FTPS (1<<3)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP (1<<7)
+#define CURLPROTO_LDAPS (1<<8)
+#define CURLPROTO_DICT (1<<9)
+#define CURLPROTO_FILE (1<<10)
+#define CURLPROTO_TFTP (1<<11)
+#define CURLPROTO_ALL (~0) /* enable everything */
+
/* long may be 32 or 64 bits, but we should never depend on anything else
but 32 */
#define CURLOPTTYPE_LONG 0
@@ -937,6 +950,18 @@
extracting it with CURLINFO_LASTSOCKET */
CINIT(CONNECT_ONLY, LONG, 141),
+ /* set the bitmask for the protocols that are allowed to be used for the
+ transfer, which thus helps the app which takes URLs from users or other
+ external inputs and want to restrict what protocol(s) to deal
+ with. Defaults to CURLPROTO_ALL. */
+ CINIT(PROTOCOLS, LONG, 181),
+
+ /* set the bitmask for the protocols that libcurl is allowed to follow to,
+ as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+ to be set in both bitmasks to be allowed to get redirected to. Defaults
+ to CURLPROTO_ALL & ~CURLPROTO_FILE. */
+ CINIT(REDIR_PROTOCOLS, LONG, 182),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
diff -r deb9cb6b2a00 lib/easy.c
--- a/lib/easy.c Wed Mar 04 16:34:52 2009 -0500
+++ b/lib/easy.c Wed Mar 04 17:25:09 2009 -0500
@@ -645,6 +645,13 @@
data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */
data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
+ /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
+ define since we internally only use the lower 16 bits for the passed
+ in bitmask to not conflict with the private bits */
+ data->set.allowed_protocols = PROT_EXTMASK;
+ data->set.redir_protocols =
+ (PROT_EXTMASK & ~CURLPROTO_FILE); /* not FILE */
+
/*
* libcurl 7.10 introduced SSL verification *by default*! This needs to be
* switched off unless wanted.
diff -r deb9cb6b2a00 lib/url.c
--- a/lib/url.c Wed Mar 04 16:34:52 2009 -0500
+++ b/lib/url.c Wed Mar 04 17:25:09 2009 -0500
@@ -341,6 +341,13 @@
data->set.httpauth = CURLAUTH_BASIC; /* defaults to basic */
data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
+ /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
+ define since we internally only use the lower 16 bits for the passed
+ in bitmask to not conflict with the private bits */
+ data->set.allowed_protocols = PROT_EXTMASK;
+ data->set.redir_protocols =
+ (PROT_EXTMASK & ~CURLPROTO_FILE); /* not FILE */
+
/* create an array with connection data struct pointers */
data->state.numconnects = 5; /* hard-coded right now */
data->state.connects = (struct connectdata **)
@@ -1486,6 +1493,22 @@
data->set.connect_only = va_arg(param, long)?TRUE:FALSE;
break;
+ case CURLOPT_PROTOCOLS:
+ /* set the bitmask for the protocols that are allowed to be used for the
+ transfer, which thus helps the app which takes URLs from users or other
+ external inputs and want to restrict what protocol(s) to deal
+ with. Defaults to CURLPROTO_ALL. */
+ data->set.allowed_protocols = va_arg(param, long) & PROT_EXTMASK;
+ break;
+
+ case CURLOPT_REDIR_PROTOCOLS:
+ /* set the bitmask for the protocols that libcurl is allowed to follow to,
+ as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+ to be set in both bitmasks to be allowed to get redirected to. Defaults
+ to CURLPROTO_ALL & ~CURLPROTO_FILE. */
+ data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK;
+ break;
+
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_FAILED_INIT; /* correct this */
@@ -3133,8 +3156,6 @@
result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
-1, NULL); /* no upload */
}
-
- return result;
#else
failf(data, LIBCURL_NAME
" was built with FILE disabled!");
@@ -3184,6 +3205,17 @@
failf(data, "Unsupported protocol: %s", conn->protostr);
return CURLE_UNSUPPORTED_PROTOCOL;
}
+ /* Protocol found. Check if allowed */
+ if(!(data->set.allowed_protocols & conn->protocol) ||
+ /* it is allowed for "normal" request, now do an extra check if this is
+ the result of a redirect */
+ (data->state.this_is_a_follow &&
+ !(data->set.redir_protocols & conn->protocol))) {
+ failf(data, "Unsupported protocol: %s", conn->protostr);
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ }
+ if (conn->protocol & PROT_FILE)
+ return result;
if(data->change.proxy && *data->change.proxy) {
/* If this is supposed to use a proxy, we need to figure out the proxy
diff -r deb9cb6b2a00 lib/urldata.h
--- a/lib/urldata.h Wed Mar 04 16:34:52 2009 -0500
+++ b/lib/urldata.h Wed Mar 04 17:25:09 2009 -0500
@@ -540,17 +540,23 @@
struct has */
long protocol; /* PROT_* flags concerning the protocol set */
-#define PROT_MISSING (1<<0)
-#define PROT_HTTP (1<<2)
-#define PROT_HTTPS (1<<3)
-#define PROT_FTP (1<<4)
-#define PROT_TELNET (1<<5)
-#define PROT_DICT (1<<6)
-#define PROT_LDAP (1<<7)
-#define PROT_FILE (1<<8)
-#define PROT_TFTP (1<<11)
-#define PROT_FTPS (1<<9)
-#define PROT_SSL (1<<10) /* protocol requires SSL */
+#define PROT_HTTP CURLPROTO_HTTP
+#define PROT_HTTPS CURLPROTO_HTTPS
+#define PROT_FTP CURLPROTO_FTP
+#define PROT_TELNET CURLPROTO_TELNET
+#define PROT_DICT CURLPROTO_DICT
+#define PROT_LDAP CURLPROTO_LDAP
+#define PROT_FILE CURLPROTO_FILE
+#define PROT_FTPS CURLPROTO_FTPS
+#define PROT_TFTP CURLPROTO_TFTP
+/* CURLPROTO_TFTP (1<<11) is currently the highest used bit in the public
+ bitmask. We make sure we use "private bits" above the first 16 to make
+ things easier. */
+
+#define PROT_EXTMASK 0xfff
+
+#define PROT_SSL (1<<22) /* protocol requires SSL */
+#define PROT_MISSING (1<<23)
/* 'dns_entry' is the particular host we use. This points to an entry in the
DNS cache and it will not get pruned while locked. It gets unlocked in
@@ -1089,6 +1095,8 @@
bool ftp_skip_ip; /* skip the IP address the FTP server passes on to
us */
bool connect_only; /* make connection, let application use the socket */
+ long allowed_protocols;
+ long redir_protocols;
};
/*
--- NEW FILE: curl-7.17.0-CVE-2009-0037.patch ---
diff -r c09f4efd2d6b docs/libcurl/curl_easy_setopt.3
--- a/docs/libcurl/curl_easy_setopt.3 Tue Mar 03 18:00:25 2009 -0500
+++ b/docs/libcurl/curl_easy_setopt.3 Wed Mar 04 17:25:26 2009 -0500
@@ -377,6 +377,26 @@
\fICURLOPT_URL\fP is the only option that \fBmust\fP be set before
\fIcurl_easy_perform(3)\fP is called.
+
+\fICURLOPT_PROTOCOLS\fP can be used to limit what protocols libcurl will use
+for this transfer, independent of what libcurl has been compiled to
+support. That may be useful if you accept the URL from an external source and
+want to limit the accessibility.
+.IP CURLOPT_PROTOCOLS
+Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
+limits what protocols libcurl may use in the transfer. This allows you to have
+a libcurl built to support a wide range of protocols but still limit specific
+transfers to only be allowed to use a subset of them. By default libcurl will
+accept all protocols it supports. See also
+\fICURLOPT_REDIR_PROTOCOLS\fP. (Added in 7.19.4)
+.IP CURLOPT_REDIR_PROTOCOLS
+Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
+limits what protocols libcurl may use in a transfer that it follows to in a
+redirect when \fICURLOPT_FOLLOWLOCATION\fP is enabled. This allows you to
+limit specific transfers to only be allowed to use a subset of protocols in
+redirections. By default libcurl will allow all protocols except for FILE and
+SCP. This is a difference compared to pre-7.19.4 versions which
+unconditionally would follow to all protocols supported. (Added in 7.19.4)
.IP CURLOPT_PROXY
Set HTTP proxy to use. The parameter should be a char * to a zero terminated
string holding the host name or dotted IP address. To specify port number in
@@ -608,6 +628,10 @@
and follow new Location: headers all the way until no more such headers are
returned. \fICURLOPT_MAXREDIRS\fP can be used to limit the number of redirects
libcurl will follow.
+
+NOTE: since 7.19.4, libcurl can limit to what protocols it will automatically
+follow. The accepted protocols are set with \fICURLOPT_REDIR_PROTOCOLS\fP and
+it excludes the FILE protocol by default.
.IP CURLOPT_UNRESTRICTED_AUTH
A non-zero parameter tells the library it can continue to send authentication
(user+password) when following locations, even when hostname changed. This
diff -r c09f4efd2d6b include/curl/curl.h
--- a/include/curl/curl.h Tue Mar 03 18:00:25 2009 -0500
+++ b/include/curl/curl.h Wed Mar 04 17:25:26 2009 -0500
@@ -539,6 +539,21 @@
CURLFTPMETHOD_LAST /* not an option, never use */
} curl_ftpmethod;
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP (1<<0)
+#define CURLPROTO_HTTPS (1<<1)
+#define CURLPROTO_FTP (1<<2)
+#define CURLPROTO_FTPS (1<<3)
+#define CURLPROTO_SCP (1<<4)
+#define CURLPROTO_SFTP (1<<5)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP (1<<7)
+#define CURLPROTO_LDAPS (1<<8)
+#define CURLPROTO_DICT (1<<9)
+#define CURLPROTO_FILE (1<<10)
+#define CURLPROTO_TFTP (1<<11)
+#define CURLPROTO_ALL (~0) /* enable everything */
+
/* long may be 32 or 64 bits, but we should never depend on anything else
but 32 */
#define CURLOPTTYPE_LONG 0
@@ -1124,6 +1139,18 @@
CINIT(NEW_FILE_PERMS, LONG, 159),
CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
+ /* set the bitmask for the protocols that are allowed to be used for the
+ transfer, which thus helps the app which takes URLs from users or other
+ external inputs and want to restrict what protocol(s) to deal
+ with. Defaults to CURLPROTO_ALL. */
+ CINIT(PROTOCOLS, LONG, 181),
+
+ /* set the bitmask for the protocols that libcurl is allowed to follow to,
+ as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+ to be set in both bitmasks to be allowed to get redirected to. Defaults
+ to CURLPROTO_ALL & ~CURLPROTO_FILE. */
+ CINIT(REDIR_PROTOCOLS, LONG, 182),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
diff -r c09f4efd2d6b lib/easy.c
--- a/lib/easy.c Tue Mar 03 18:00:25 2009 -0500
+++ b/lib/easy.c Wed Mar 04 17:25:26 2009 -0500
@@ -742,6 +742,13 @@
type */
data->set.new_file_perms = 0644; /* Default permissions */
data->set.new_directory_perms = 0755; /* Default permissions */
+
+ /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
+ define since we internally only use the lower 16 bits for the passed
+ in bitmask to not conflict with the private bits */
+ data->set.allowed_protocols = PROT_EXTMASK;
+ data->set.redir_protocols =
+ PROT_EXTMASK & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
}
#ifdef CURL_DOES_CONVERSIONS
diff -r c09f4efd2d6b lib/url.c
--- a/lib/url.c Tue Mar 03 18:00:25 2009 -0500
+++ b/lib/url.c Wed Mar 04 17:25:26 2009 -0500
@@ -648,6 +648,13 @@
data->set.new_file_perms = 0644; /* Default permissions */
data->set.new_directory_perms = 0755; /* Default permissions */
+ /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
+ define since we internally only use the lower 16 bits for the passed
+ in bitmask to not conflict with the private bits */
+ data->set.allowed_protocols = PROT_EXTMASK;
+ data->set.redir_protocols =
+ PROT_EXTMASK & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
+
/* most recent connection is not yet defined */
data->state.lastconnect = -1;
@@ -1858,6 +1865,22 @@
data->set.new_directory_perms = va_arg(param, long);
break;
+ case CURLOPT_PROTOCOLS:
+ /* set the bitmask for the protocols that are allowed to be used for the
+ transfer, which thus helps the app which takes URLs from users or other
+ external inputs and want to restrict what protocol(s) to deal
+ with. Defaults to CURLPROTO_ALL. */
+ data->set.allowed_protocols = va_arg(param, long) & PROT_EXTMASK;
+ break;
+
+ case CURLOPT_REDIR_PROTOCOLS:
+ /* set the bitmask for the protocols that libcurl is allowed to follow to,
+ as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+ to be set in both bitmasks to be allowed to get redirected to. Defaults
+ to CURLPROTO_ALL & ~CURLPROTO_FILE. */
+ data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK;
+ break;
+
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_FAILED_INIT; /* correct this */
@@ -3176,6 +3199,17 @@
failf(data, "Unsupported protocol: %s", conn->protostr);
return CURLE_UNSUPPORTED_PROTOCOL;
}
+
+ /* Protocol found. Check if allowed */
+ if(!(data->set.allowed_protocols & conn->protocol) ||
+ /* it is allowed for "normal" request, now do an extra check if this is
+ the result of a redirect */
+ (data->state.this_is_a_follow &&
+ !(data->set.redir_protocols & conn->protocol))) {
+ failf(data, "Unsupported protocol: %s", conn->protostr);
+ return CURLE_UNSUPPORTED_PROTOCOL;
+ }
+
return CURLE_OK;
}
diff -r c09f4efd2d6b lib/urldata.h
--- a/lib/urldata.h Tue Mar 03 18:00:25 2009 -0500
+++ b/lib/urldata.h Wed Mar 04 17:25:26 2009 -0500
@@ -817,19 +817,26 @@
long connectindex; /* what index in the connection cache connects index this
particular struct has */
long protocol; /* PROT_* flags concerning the protocol set */
-#define PROT_MISSING (1<<0)
-#define PROT_HTTP (1<<2)
-#define PROT_HTTPS (1<<3)
-#define PROT_FTP (1<<4)
-#define PROT_TELNET (1<<5)
-#define PROT_DICT (1<<6)
-#define PROT_LDAP (1<<7)
-#define PROT_FILE (1<<8)
-#define PROT_FTPS (1<<9)
-#define PROT_SSL (1<<10) /* protocol requires SSL */
-#define PROT_TFTP (1<<11)
-#define PROT_SCP (1<<12)
-#define PROT_SFTP (1<<13)
+#define PROT_HTTP CURLPROTO_HTTP
+#define PROT_HTTPS CURLPROTO_HTTPS
+#define PROT_FTP CURLPROTO_FTP
+#define PROT_TELNET CURLPROTO_TELNET
+#define PROT_DICT CURLPROTO_DICT
+#define PROT_LDAP CURLPROTO_LDAP
+#define PROT_FILE CURLPROTO_FILE
+#define PROT_FTPS CURLPROTO_FTPS
+#define PROT_TFTP CURLPROTO_TFTP
+#define PROT_SCP CURLPROTO_SCP
+#define PROT_SFTP CURLPROTO_SFTP
+
+/* CURLPROTO_TFTP (1<<11) is currently the highest used bit in the public
+ bitmask. We make sure we use "private bits" above the first 16 to make
+ things easier. */
+
+#define PROT_EXTMASK 0xfff
+
+#define PROT_SSL (1<<22) /* protocol requires SSL */
+#define PROT_MISSING (1<<23)
#define PROT_CLOSEACTION PROT_FTP /* these ones need action before socket
close */
@@ -1423,6 +1430,8 @@
long new_directory_perms; /* Permissions to use when creating remote dirs */
char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
+ long allowed_protocols;
+ long redir_protocols;
};
struct Names {