| ------------------------------------------------------------------------ |
| r1804691 | danielsh | 2017-08-10 11:14:13 -0700 (Thu, 10 Aug 2017) | 18 lines |
| |
| Fix CVE-2017-9800. |
| |
| See: https://subversion.apache.org/security/CVE-2017-0800-advisory.txt |
| |
| * subversion/libsvn_ra_svn/client.c |
| (svn_ctype.h): Include. |
| (find_tunnel_agent): Pass a "--" end-of-options guard to ssh. |
| Expect the 'hostinfo' parameter to be URI-decoded. |
| (is_valid_hostinfo): New. |
| (ra_svn_open): Validate the hostname before using it. |
| |
| * subversion/libsvn_subr/config_file.c |
| (svn_config_ensure): Update the example configuration likewise. |
| |
| Patch by: philip |
| Review by: danielsh |
| stsp |
| astieger (earlier version) |
| |
| Upstream-Status: Backport |
| http://svn.apache.org/viewvc?view=revision&sortby=rev&revision=1804691 |
| |
| CVE: CVE-2017-9800 |
| |
| Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com> |
| --- |
| Index: subversion/libsvn_subr/config_file.c |
| =================================================================== |
| --- subversion/libsvn_subr/config_file.c (revision 1804690) |
| +++ subversion/libsvn_subr/config_file.c (revision 1804691) |
| @@ -1448,12 +1448,12 @@ |
| "### passed to the tunnel agent as <user>@<hostname>.) If the" NL |
| "### built-in ssh scheme were not predefined, it could be defined" NL |
| "### as:" NL |
| - "# ssh = $SVN_SSH ssh -q" NL |
| + "# ssh = $SVN_SSH ssh -q --" NL |
| "### If you wanted to define a new 'rsh' scheme, to be used with" NL |
| "### 'svn+rsh:' URLs, you could do so as follows:" NL |
| - "# rsh = rsh" NL |
| + "# rsh = rsh --" NL |
| "### Or, if you wanted to specify a full path and arguments:" NL |
| - "# rsh = /path/to/rsh -l myusername" NL |
| + "# rsh = /path/to/rsh -l myusername --" NL |
| "### On Windows, if you are specifying a full path to a command," NL |
| "### use a forward slash (/) or a paired backslash (\\\\) as the" NL |
| "### path separator. A single backslash will be treated as an" NL |
| Index: subversion/libsvn_ra_svn/client.c |
| =================================================================== |
| --- subversion/libsvn_ra_svn/client.c (revision 1804690) |
| +++ subversion/libsvn_ra_svn/client.c (revision 1804691) |
| @@ -46,6 +46,7 @@ |
| #include "svn_props.h" |
| #include "svn_mergeinfo.h" |
| #include "svn_version.h" |
| +#include "svn_ctype.h" |
| |
| #include "svn_private_config.h" |
| |
| @@ -398,7 +399,7 @@ |
| * versions have it too. If the user is using some other ssh |
| * implementation that doesn't accept it, they can override it |
| * in the [tunnels] section of the config. */ |
| - val = "$SVN_SSH ssh -q"; |
| + val = "$SVN_SSH ssh -q --"; |
| } |
| |
| if (!val || !*val) |
| @@ -443,7 +444,7 @@ |
| for (n = 0; cmd_argv[n] != NULL; n++) |
| argv[n] = cmd_argv[n]; |
| |
| - argv[n++] = svn_path_uri_decode(hostinfo, pool); |
| + argv[n++] = hostinfo; |
| argv[n++] = "svnserve"; |
| argv[n++] = "-t"; |
| argv[n] = NULL; |
| @@ -811,7 +812,33 @@ |
| } |
| |
| |
| +/* A simple whitelist to ensure the following are valid: |
| + * user@server |
| + * [::1]:22 |
| + * server-name |
| + * server_name |
| + * 127.0.0.1 |
| + * with an extra restriction that a leading '-' is invalid. |
| + */ |
| +static svn_boolean_t |
| +is_valid_hostinfo(const char *hostinfo) |
| +{ |
| + const char *p = hostinfo; |
| |
| + if (p[0] == '-') |
| + return FALSE; |
| + |
| + while (*p) |
| + { |
| + if (!svn_ctype_isalnum(*p) && !strchr(":.-_[]@", *p)) |
| + return FALSE; |
| + |
| + ++p; |
| + } |
| + |
| + return TRUE; |
| +} |
| + |
| static svn_error_t *ra_svn_open(svn_ra_session_t *session, |
| const char **corrected_url, |
| const char *url, |
| @@ -844,8 +871,18 @@ |
| || (callbacks->check_tunnel_func && callbacks->open_tunnel_func |
| && !callbacks->check_tunnel_func(callbacks->tunnel_baton, |
| tunnel)))) |
| - SVN_ERR(find_tunnel_agent(tunnel, uri.hostinfo, &tunnel_argv, config, |
| - result_pool)); |
| + { |
| + const char *decoded_hostinfo; |
| + |
| + decoded_hostinfo = svn_path_uri_decode(uri.hostinfo, result_pool); |
| + |
| + if (!is_valid_hostinfo(decoded_hostinfo)) |
| + return svn_error_createf(SVN_ERR_BAD_URL, NULL, _("Invalid host '%s'"), |
| + uri.hostinfo); |
| + |
| + SVN_ERR(find_tunnel_agent(tunnel, decoded_hostinfo, &tunnel_argv, |
| + config, result_pool)); |
| + } |
| else |
| tunnel_argv = NULL; |
| |
| |
| ------------------------------------------------------------------------ |