diff --git a/.gitignore b/.gitignore index a8b6c5d..77221d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *~ *.rpm *.tar.gz +*.tar.xz /.build*.log /git-*/ diff --git a/0001-Fix-CVE-2016-2315-CVE-2016-2324.patch b/0001-Fix-CVE-2016-2315-CVE-2016-2324.patch new file mode 100644 index 0000000..082a1a2 --- /dev/null +++ b/0001-Fix-CVE-2016-2315-CVE-2016-2324.patch @@ -0,0 +1,116 @@ +From 5857966a36f9c553e73e375455a246896aeba73f Mon Sep 17 00:00:00 2001 +From: Petr Stodulka +Date: Fri, 18 Mar 2016 17:14:32 +0100 +Subject: [PATCH] Fix CVE-2016-2315 CVE-2016-2324 + +- added upstream macros for detecting size_t overflow (much more just + for easier related changes in future, if we want to do some yet) +- upstream solution removes function path_name() and modify all related + part of code to replace this function. However, it's too hard for + backport to such old version of git without unchanged behaviour, + so application just die with error message instead. +--- + diff.h | 4 ++-- + git-compat-util.h | 34 ++++++++++++++++++++++++++++++++++ + revision.c | 11 ++++++++--- + 3 files changed, 44 insertions(+), 5 deletions(-) + +diff --git a/diff.h b/diff.h +index 78b4091..18dabf0 100644 +--- a/diff.h ++++ b/diff.h +@@ -201,8 +201,8 @@ struct combine_diff_path { + } parent[FLEX_ARRAY]; + }; + #define combine_diff_path_size(n, l) \ +- (sizeof(struct combine_diff_path) + \ +- sizeof(struct combine_diff_parent) * (n) + (l) + 1) ++ st_add4(sizeof(struct combine_diff_path), (l), 1, \ ++ st_mult(sizeof(struct combine_diff_parent), (n))) + + extern void show_combined_diff(struct combine_diff_path *elem, int num_parent, + int dense, struct rev_info *); +diff --git a/git-compat-util.h b/git-compat-util.h +index ad47624..77a7031 100644 +--- a/git-compat-util.h ++++ b/git-compat-util.h +@@ -46,6 +46,14 @@ + #define unsigned_add_overflows(a, b) \ + ((b) > maximum_unsigned_value_of_type(a) - (a)) + ++/* ++ * Returns true if the multiplication of "a" and "b" will ++ * overflow. The types of "a" and "b" must match and must be unsigned. ++ * Note that this macro evaluates "a" twice! ++ */ ++#define unsigned_mult_overflows(a, b) \ ++ ((a) && (b) > maximum_unsigned_value_of_type(a) / (a)) ++ + #ifdef __GNUC__ + #define TYPEOF(x) (__typeof__(x)) + #else +@@ -490,6 +498,32 @@ static inline void *gitmempcpy(void *dest, const void *src, size_t n) + } + #endif + ++static inline size_t st_add(size_t a, size_t b) ++{ ++ if (unsigned_add_overflows(a, b)) ++ die("size_t overflow: %"PRIuMAX" + %"PRIuMAX, ++ (uintmax_t)a, (uintmax_t)b); ++ return a + b; ++} ++#define st_add3(a,b,c) st_add((a),st_add((b),(c))) ++#define st_add4(a,b,c,d) st_add((a),st_add3((b),(c),(d))) ++ ++static inline size_t st_mult(size_t a, size_t b) ++{ ++ if (unsigned_mult_overflows(a, b)) ++ die("size_t overflow: %"PRIuMAX" * %"PRIuMAX, ++ (uintmax_t)a, (uintmax_t)b); ++ return a * b; ++} ++ ++static inline size_t st_sub(size_t a, size_t b) ++{ ++ if (a < b) ++ die("size_t underflow: %"PRIuMAX" - %"PRIuMAX, ++ (uintmax_t)a, (uintmax_t)b); ++ return a - b; ++} ++ + #ifdef NO_INET_PTON + int inet_pton(int af, const char *src, void *dst); + #endif +diff --git a/revision.c b/revision.c +index 9df13ca..7e358ef 100644 +--- a/revision.c ++++ b/revision.c +@@ -21,16 +21,21 @@ char *path_name(const struct name_path *path, const char *name) + { + const struct name_path *p; + char *n, *m; +- int nlen = strlen(name); +- int len = nlen + 1; ++ size_t nlen = strlen(name); ++ size_t len = st_add(nlen, 1); ++ ++ if(len >= INT_MAX) ++ die("path_name(): path is too long."); + + for (p = path; p; p = p->up) { + if (p->elem_len) + len += p->elem_len + 1; ++ if(len >= INT_MAX) ++ die("path_name(): path is too long."); + } + n = xmalloc(len); + m = n + len - (nlen + 1); +- strcpy(m, name); ++ memcpy(m, name, nlen + 1); + for (p = path; p; p = p->up) { + if (p->elem_len) { + m -= p->elem_len + 1; +-- +2.8.1 + diff --git a/0001-submodule-allow-only-certain-protocols-for-submodule.patch b/0001-submodule-allow-only-certain-protocols-for-submodule.patch new file mode 100644 index 0000000..e2067b1 --- /dev/null +++ b/0001-submodule-allow-only-certain-protocols-for-submodule.patch @@ -0,0 +1,104 @@ +From 6d69680505dbbc484178105815ed624fab40b2de Mon Sep 17 00:00:00 2001 +From: Petr Stodulka +Date: Wed, 28 Oct 2015 15:03:01 +0100 +Subject: [PATCH 1/5] submodule: allow only certain protocols for submodule + fetches + +Some protocols (like git-remote-ext) can execute arbitrary +code found in the URL. The URLs that submodules use may come +from arbitrary sources (e.g., .gitmodules files in a remote +repository). Let's restrict submodules to fetching from a +known-good subset of protocols. + +Note that we apply this restriction to all submodule +commands, whether the URL comes from .gitmodules or not. +This is more restrictive than we need to be; for example, in +the tests we run: + + git submodule add ext::... + +which should be trusted, as the URL comes directly from the +command line provided by the user. But doing it this way is +simpler, and makes it much less likely that we would miss a +case. And since such protocols should be an exception +(especially because nobody who clones from them will be able +to update the submodules!), it's not likely to inconvenience +anyone in practice. +--- + git-submodule.sh | 9 +++++++++ + t/t5815-submodule-protos-sh | 43 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 52 insertions(+) + create mode 100644 t/t5815-submodule-protos-sh + +diff --git a/git-submodule.sh b/git-submodule.sh +index 79bfaac..bec3362 100755 +--- a/git-submodule.sh ++++ b/git-submodule.sh +@@ -19,6 +19,15 @@ OPTIONS_SPEC= + . git-parse-remote + require_work_tree + ++# Restrict ourselves to a vanilla subset of protocols; the URLs ++# we get are under control of a remote repository, and we do not ++# want them kicking off arbitrary git-remote-* programs. ++# ++# If the user has already specified a set of allowed protocols, ++# we assume they know what they're doing and use that instead. ++: ${GIT_ALLOW_PROTOCOL=file:git:http:https:ssh} ++export GIT_ALLOW_PROTOCOL ++ + command= + branch= + force= +diff --git a/t/t5815-submodule-protos-sh b/t/t5815-submodule-protos-sh +new file mode 100644 +index 0000000..06f55a1 +--- /dev/null ++++ b/t/t5815-submodule-protos-sh +@@ -0,0 +1,43 @@ ++#!/bin/sh ++ ++test_description='test protocol whitelisting with submodules' ++. ./test-lib.sh ++. "$TEST_DIRECTORY"/lib-proto-disable.sh ++ ++setup_ext_wrapper ++setup_ssh_wrapper ++ ++test_expect_success 'setup repository with submodules' ' ++ mkdir remote && ++ git init remote/repo.git && ++ (cd remote/repo.git && test_commit one) && ++ # submodule-add should probably trust what we feed it on the cmdline, ++ # but its implementation is overly conservative. ++ GIT_ALLOW_PROTOCOL=ssh git submodule add remote:repo.git ssh-module && ++ GIT_ALLOW_PROTOCOL=ext git submodule add "ext::fake-remote %S repo.git" ext-module && ++ git commit -m "add submodules" ++' ++ ++test_expect_success 'clone with recurse-submodules fails' ' ++ test_must_fail git clone --recurse-submodules . dst ++' ++ ++test_expect_success 'setup individual updates' ' ++ rm -rf dst && ++ git clone . dst && ++ git -C dst submodule init ++' ++ ++test_expect_success 'update of ssh allowed' ' ++ git -C dst submodule update ssh-module ++' ++ ++test_expect_success 'update of ext not allowed' ' ++ test_must_fail git -C dst submodule update ext-module ++' ++ ++test_expect_success 'user can override whitelist' ' ++ GIT_ALLOW_PROTOCOL=ext git -C dst submodule update ext-module ++' ++ ++test_done +-- +2.1.0 + diff --git a/0002-transport-add-a-protocol-whitelist-environment-varia.patch b/0002-transport-add-a-protocol-whitelist-environment-varia.patch new file mode 100644 index 0000000..d908739 --- /dev/null +++ b/0002-transport-add-a-protocol-whitelist-environment-varia.patch @@ -0,0 +1,207 @@ +From cfa4e13f09d07f679ffacdddfbe0ef44d1de32d9 Mon Sep 17 00:00:00 2001 +From: Petr Stodulka +Date: Wed, 28 Oct 2015 15:21:08 +0100 +Subject: [PATCH 2/5] transport: add a protocol-whitelist environment variable + +If we are cloning an untrusted remote repository into a +sandbox, we may also want to fetch remote submodules in +order to get the complete view as intended by the other +side. However, that opens us up to attacks where a malicious +user gets us to clone something they would not otherwise +have access to (this is not necessarily a problem by itself, +but we may then act on the cloned contents in a way that +exposes them to the attacker). + +Ideally such a setup would sandbox git entirely away from +high-value items, but this is not always practical or easy +to set up (e.g., OS network controls may block multiple +protocols, and we would want to enable some but not others). + +We can help this case by providing a way to restrict +particular protocols. We use a whitelist in the environment. +This is more annoying to set up than a blacklist, but +defaults to safety if the set of protocols git supports +grows). If no whitelist is specified, we continue to default +to allowing all protocols (this is an "unsafe" default, but +since the minority of users will want this sandboxing +effect, it is the only sensible one). + +A note on the tests: ideally these would all be in a single +test file, but the git-daemon and httpd test infrastructure +is an all-or-nothing proposition rather than a test-by-test +prerequisite. By putting them all together, we would be +unable to test the file-local code on machines without +apache. +--- + Documentation/git.txt | 32 ++++++++++++++++++++++++++++++++ + connect.c | 4 ++++ + transport-helper.c | 2 ++ + transport.c | 21 ++++++++++++++++++++- + transport.h | 7 +++++++ + 5 files changed, 65 insertions(+), 1 deletion(-) + +diff --git a/Documentation/git.txt b/Documentation/git.txt +index 443d88f..179a0e8 100644 +--- a/Documentation/git.txt ++++ b/Documentation/git.txt +@@ -847,6 +847,38 @@ GIT_LITERAL_PATHSPECS:: + literal paths to Git (e.g., paths previously given to you by + `git ls-tree`, `--raw` diff output, etc). + ++`GIT_ALLOW_PROTOCOL`:: ++ If set, provide a colon-separated list of protocols which are ++ allowed to be used with fetch/push/clone. This is useful to ++ restrict recursive submodule initialization from an untrusted ++ repository. Any protocol not mentioned will be disallowed (i.e., ++ this is a whitelist, not a blacklist). If the variable is not ++ set at all, all protocols are enabled. The protocol names ++ currently used by git are: ++ ++ - `file`: any local file-based path (including `file://` URLs, ++ or local paths) ++ ++ - `git`: the anonymous git protocol over a direct TCP ++ connection (or proxy, if configured) ++ ++ - `ssh`: git over ssh (including `host:path` syntax, ++ `git+ssh://`, etc). ++ ++ - `rsync`: git over rsync ++ ++ - `http`: git over http, both "smart http" and "dumb http". ++ Note that this does _not_ include `https`; if you want both, ++ you should specify both as `http:https`. ++ ++ - any external helpers are named by their protocol (e.g., use ++ `hg` to allow the `git-remote-hg` helper) +++ ++Note that this controls only git's internal protocol selection. ++If libcurl is used (e.g., by the `http` transport), it may ++redirect to other protocols. There is not currently any way to ++restrict this. ++ + + Discussion[[Discussion]] + ------------------------ +diff --git a/connect.c b/connect.c +index f57efd0..6d4ea13 100644 +--- a/connect.c ++++ b/connect.c +@@ -6,6 +6,7 @@ + #include "run-command.h" + #include "remote.h" + #include "url.h" ++#include "transport.h" + + static char *server_capabilities; + +@@ -587,6 +588,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig, + * cannot connect. + */ + char *target_host = xstrdup(host); ++ transport_check_allowed("git"); + if (git_use_proxy(host)) + conn = git_proxy_connect(fd, host); + else +@@ -623,6 +625,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig, + if (protocol == PROTO_SSH) { + const char *ssh = getenv("GIT_SSH"); + int putty = ssh && strcasestr(ssh, "plink"); ++ transport_check_allowed("ssh"); + if (!ssh) ssh = "ssh"; + + *arg++ = ssh; +@@ -639,6 +642,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig, + /* remove repo-local variables from the environment */ + conn->env = local_repo_env; + conn->use_shell = 1; ++ transport_check_allowed("file"); + } + *arg++ = cmd.buf; + *arg = NULL; +diff --git a/transport-helper.c b/transport-helper.c +index 522d791..be8402a 100644 +--- a/transport-helper.c ++++ b/transport-helper.c +@@ -932,6 +932,8 @@ int transport_helper_init(struct transport *transport, const char *name) + struct helper_data *data = xcalloc(sizeof(*data), 1); + data->name = name; + ++ transport_check_allowed(name); ++ + if (getenv("GIT_TRANSPORT_HELPER_DEBUG")) + debug = 1; + +diff --git a/transport.c b/transport.c +index ba5d8af..733717d 100644 +--- a/transport.c ++++ b/transport.c +@@ -894,6 +894,20 @@ static int external_specification_len(const char *url) + return strchr(url, ':') - url; + } + ++void transport_check_allowed(const char *type) ++{ ++ struct string_list allowed = STRING_LIST_INIT_DUP; ++ const char *v = getenv("GIT_ALLOW_PROTOCOL"); ++ ++ if (!v) ++ return; ++ ++ string_list_split(&allowed, v, ':', -1); ++ if (!unsorted_string_list_has_string(&allowed, type)) ++ die("transport '%s' not allowed", type); ++ string_list_clear(&allowed, 0); ++} ++ + struct transport *transport_get(struct remote *remote, const char *url) + { + const char *helper; +@@ -925,12 +939,14 @@ struct transport *transport_get(struct remote *remote, const char *url) + if (helper) { + transport_helper_init(ret, helper); + } else if (!prefixcmp(url, "rsync:")) { ++ transport_check_allowed("rsync"); + ret->get_refs_list = get_refs_via_rsync; + ret->fetch = fetch_objs_via_rsync; + ret->push = rsync_transport_push; + ret->smart_options = NULL; + } else if (is_local(url) && is_file(url) && is_bundle(url, 1)) { + struct bundle_transport_data *data = xcalloc(1, sizeof(*data)); ++ transport_check_allowed("file"); + ret->data = data; + ret->get_refs_list = get_refs_from_bundle; + ret->fetch = fetch_refs_from_bundle; +@@ -942,7 +958,10 @@ struct transport *transport_get(struct remote *remote, const char *url) + || !prefixcmp(url, "ssh://") + || !prefixcmp(url, "git+ssh://") + || !prefixcmp(url, "ssh+git://")) { +- /* These are builtin smart transports. */ ++ /* ++ * These are builtin smart transports; "allowed" transports ++ * will be checked individually in git_connect. ++ */ + struct git_transport_data *data = xcalloc(1, sizeof(*data)); + ret->data = data; + ret->set_option = NULL; +diff --git a/transport.h b/transport.h +index fcb1d25..2beda7d 100644 +--- a/transport.h ++++ b/transport.h +@@ -113,6 +113,13 @@ struct transport { + /* Returns a transport suitable for the url */ + struct transport *transport_get(struct remote *, const char *); + ++/* ++ * Check whether a transport is allowed by the environment, ++ * and die otherwise. type should generally be the URL scheme, ++ * as described in Documentation/git.txt ++ */ ++void transport_check_allowed(const char *type); ++ + /* Transport options which apply to git:// and scp-style URLs */ + + /* The program to use on the remote side to send a pack */ +-- +2.1.0 + diff --git a/0003-transport-refactor-protocol-whitelist-code.patch b/0003-transport-refactor-protocol-whitelist-code.patch new file mode 100644 index 0000000..ff5416d --- /dev/null +++ b/0003-transport-refactor-protocol-whitelist-code.patch @@ -0,0 +1,107 @@ +From 9b9aabe6ab5d07227c1c02781f03a3c38fbc27b0 Mon Sep 17 00:00:00 2001 +From: Jeff King +Date: Tue, 22 Sep 2015 18:03:49 -0400 +Subject: [PATCH 3/5] transport: refactor protocol whitelist code + +The current callers only want to die when their transport is +prohibited. But future callers want to query the mechanism +without dying. + +Let's break out a few query functions, and also save the +results in a static list so we don't have to re-parse for +each query. + +Based-on-a-patch-by: Blake Burkhart +Signed-off-by: Jeff King +Signed-off-by: Junio C Hamano +--- + transport.c | 38 ++++++++++++++++++++++++++++++-------- + transport.h | 15 +++++++++++++-- + 2 files changed, 43 insertions(+), 10 deletions(-) + +diff --git a/transport.c b/transport.c +index 733717d..2dbdca0 100644 +--- a/transport.c ++++ b/transport.c +@@ -894,18 +894,40 @@ static int external_specification_len(const char *url) + return strchr(url, ':') - url; + } + +-void transport_check_allowed(const char *type) ++static const struct string_list *protocol_whitelist(void) + { +- struct string_list allowed = STRING_LIST_INIT_DUP; +- const char *v = getenv("GIT_ALLOW_PROTOCOL"); ++ static int enabled = -1; ++ static struct string_list allowed = STRING_LIST_INIT_DUP; ++ ++ if (enabled < 0) { ++ const char *v = getenv("GIT_ALLOW_PROTOCOL"); ++ if (v) { ++ string_list_split(&allowed, v, ':', -1); ++ sort_string_list(&allowed); ++ enabled = 1; ++ } else { ++ enabled = 0; ++ } ++ } + +- if (!v) +- return; ++ return enabled ? &allowed : NULL; ++} ++ ++int is_transport_allowed(const char *type) ++{ ++ const struct string_list *allowed = protocol_whitelist(); ++ return !allowed || string_list_has_string(allowed, type); ++} + +- string_list_split(&allowed, v, ':', -1); +- if (!unsorted_string_list_has_string(&allowed, type)) ++void transport_check_allowed(const char *type) ++{ ++ if (!is_transport_allowed(type)) + die("transport '%s' not allowed", type); +- string_list_clear(&allowed, 0); ++} ++ ++int transport_restrict_protocols(void) ++{ ++ return !!protocol_whitelist(); + } + + struct transport *transport_get(struct remote *remote, const char *url) +diff --git a/transport.h b/transport.h +index 2beda7d..7707c27 100644 +--- a/transport.h ++++ b/transport.h +@@ -114,12 +114,23 @@ struct transport { + struct transport *transport_get(struct remote *, const char *); + + /* ++ * Check whether a transport is allowed by the environment. Type should ++ * generally be the URL scheme, as described in Documentation/git.txt ++ */ ++int is_transport_allowed(const char *type); ++ ++/* + * Check whether a transport is allowed by the environment, +- * and die otherwise. type should generally be the URL scheme, +- * as described in Documentation/git.txt ++ * and die otherwise. + */ + void transport_check_allowed(const char *type); + ++/* ++ * Returns true if the user has attempted to turn on protocol ++ * restrictions at all. ++ */ ++int transport_restrict_protocols(void); ++ + /* Transport options which apply to git:// and scp-style URLs */ + + /* The program to use on the remote side to send a pack */ +-- +2.1.0 + diff --git a/0004-http-limit-redirection-to-protocol-whitelist.patch b/0004-http-limit-redirection-to-protocol-whitelist.patch new file mode 100644 index 0000000..19a6b8c --- /dev/null +++ b/0004-http-limit-redirection-to-protocol-whitelist.patch @@ -0,0 +1,77 @@ +From 0f032880eddc09abd1850533422c9b0bb80a010c Mon Sep 17 00:00:00 2001 +From: Petr Stodulka +Date: Sun, 1 Nov 2015 20:23:07 +0100 +Subject: [PATCH] http-limit-redirection-to-protocol-whitelist + +Previously, libcurl would follow redirection to any protocol +it was compiled for support with. This is desirable to allow +redirection from HTTP to HTTPS. However, it would even +successfully allow redirection from HTTP to SFTP, a protocol +that git does not otherwise support at all. Furthermore +git's new protocol-whitelisting could be bypassed by +following a redirect within the remote helper, as it was +only enforced at transport selection time. + +This patch limits redirects within libcurl to HTTP, HTTPS, +FTP and FTPS. If there is a protocol-whitelist present, this +list is limited to those also allowed by the whitelist. As +redirection happens from within libcurl, it is impossible +for an HTTP redirect to a protocol implemented within +another remote helper. + +When the curl version git was compiled with is too old to +support restrictions on protocol redirection, we warn the +user if GIT_ALLOW_PROTOCOL restrictions were requested. This +is a little inaccurate, as even without that variable in the +environment, we would still restrict SFTP, etc, and we do +not warn in that case. But anything else means we would +literally warn every time git accesses an http remote. +--- + http.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/http.c b/http.c +index d9d1aad..744e5a1 100644 +--- a/http.c ++++ b/http.c +@@ -5,6 +5,7 @@ + #include "url.h" + #include "credential.h" + #include "version.h" ++#include "transport.h" + + int active_requests; + int http_is_verbose; +@@ -246,6 +247,7 @@ static int has_cert_password(void) + static CURL *get_curl_handle(void) + { + CURL *result = curl_easy_init(); ++ long allowed_protocols = 0; + + if (!curl_ssl_verify) { + curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 0); +@@ -296,6 +298,21 @@ static CURL *get_curl_handle(void) + #elif LIBCURL_VERSION_NUM >= 0x071101 + curl_easy_setopt(result, CURLOPT_POST301, 1); + #endif ++#if LIBCURL_VERSION_NUM >= 0x071304 ++ if (is_transport_allowed("http")) ++ allowed_protocols |= CURLPROTO_HTTP; ++ if (is_transport_allowed("https")) ++ allowed_protocols |= CURLPROTO_HTTPS; ++ if (is_transport_allowed("ftp")) ++ allowed_protocols |= CURLPROTO_FTP; ++ if (is_transport_allowed("ftps")) ++ allowed_protocols |= CURLPROTO_FTPS; ++ curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS, allowed_protocols); ++#else ++ if (transport_restrict_protocols()) ++ warning("protocol restrictions not applied to curl redirects because\n" ++ "your curl version is too old (>= 7.19.4)"); ++#endif + + if (getenv("GIT_CURL_VERBOSE")) + curl_easy_setopt(result, CURLOPT_VERBOSE, 1); +-- +2.4.3 + diff --git a/0005-http-limit-redirection-depth.patch b/0005-http-limit-redirection-depth.patch new file mode 100644 index 0000000..471f4eb --- /dev/null +++ b/0005-http-limit-redirection-depth.patch @@ -0,0 +1,31 @@ +From 7f3bfdbc2670b4960242fa1b229dde6bcb2b463b Mon Sep 17 00:00:00 2001 +From: Petr Stodulka +Date: Fri, 23 Oct 2015 17:39:59 +0200 +Subject: [PATCH 5/5] http: limit redirection depth + +By default, libcurl will follow circular http redirects +forever. Let's put a cap on this so that somebody who can +trigger an automated fetch of an arbitrary repository (e.g., +for CI) cannot convince git to loop infinitely. + +The value chosen is 20, which is the same default that +Firefox uses. +--- + http.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/http.c b/http.c +index 235c2d5..a1c7dcb 100644 +--- a/http.c ++++ b/http.c +@@ -298,6 +298,7 @@ static CURL *get_curl_handle(void) + } + + curl_easy_setopt(result, CURLOPT_FOLLOWLOCATION, 1); ++ curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20); + #if LIBCURL_VERSION_NUM >= 0x071301 + curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL); + #elif LIBCURL_VERSION_NUM >= 0x071101 +-- +2.1.0 + diff --git a/0007-git-prompt.patch b/0007-git-prompt.patch new file mode 100644 index 0000000..a179403 --- /dev/null +++ b/0007-git-prompt.patch @@ -0,0 +1,53 @@ +From 7e546ae76da784185ba9515ed86e435ba17fdd65 Mon Sep 17 00:00:00 2001 +From: Petr Stodulka +Date: Wed, 29 Mar 2017 13:08:28 +0200 +Subject: [PATCH] git-prompt.sh: don't put unsanitized branch names in $PS1 + +--- + contrib/completion/git-prompt.sh | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh +index eaf5c36..2c872e5 100644 +--- a/contrib/completion/git-prompt.sh ++++ b/contrib/completion/git-prompt.sh +@@ -360,8 +360,11 @@ __git_ps1 () + fi + + local f="$w$i$s$u" ++ b=${b##refs/heads/} + if [ $pcmode = yes ]; then + local gitstring= ++ __git_ps1_branch_name=$b ++ b="\${__git_ps1_branch_name}" + if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then + local c_red='\e[31m' + local c_green='\e[32m' +@@ -371,7 +374,7 @@ __git_ps1 () + local ok_color=$c_green + local branch_color="$c_clear" + local flags_color="$c_lblue" +- local branchstring="$c${b##refs/heads/}" ++ local branchstring="$c$b" + + if [ $detached = no ]; then + branch_color="$ok_color" +@@ -400,13 +403,13 @@ __git_ps1 () + fi + gitstring="$gitstring\[$c_clear\]$r$p" + else +- gitstring="$c${b##refs/heads/}${f:+ $f}$r$p" ++ gitstring="$c$b${f:+ $f}$r$p" + fi + gitstring=$(printf -- "$printf_format" "$gitstring") + PS1="$ps1pc_start$gitstring$ps1pc_end" + else + # NO color option unless in PROMPT_COMMAND mode +- printf -- "$printf_format" "$c${b##refs/heads/}${f:+ $f}$r$p" ++ printf -- "$printf_format" "$c$b${f:+ $f}$r$p" + fi + fi + } +-- +2.5.5 + diff --git a/git.spec b/git.spec index 5a1966b..5cd6728 100644 --- a/git.spec +++ b/git.spec @@ -43,20 +43,20 @@ %endif Name: git -Version: 1.8.2.1 -Release: 1%{?dist} +Version: 1.8.2.3 +Release: 2%{?dist} Summary: Fast Version Control System License: GPLv2 Group: Development/Tools URL: http://git-scm.com/ -Source0: http://git-core.googlecode.com/files/%{name}-%{version}.tar.gz +Source0: https://www.kernel.org/pub/software/scm/git/%{name}-%{version}.tar.xz Source2: git-init.el Source3: git.xinetd.in Source4: git.conf.httpd Source5: git-gui.desktop Source6: gitweb.conf.in -Source10: http://git-core.googlecode.com/files/%{name}-manpages-%{version}.tar.gz -Source11: http://git-core.googlecode.com/files/%{name}-htmldocs-%{version}.tar.gz +Source10: https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/git-core/%{name}-manpages-%{version}.tar.gz +Source11: https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/git-core/%{name}-htmldocs-%{version}.tar.gz Patch0: git-1.5-gitweb-home-link.patch # https://bugzilla.redhat.com/490602 Patch1: git-cvsimport-Ignore-cvsps-2.2b1-Branches-output.patch @@ -66,6 +66,15 @@ Patch5: 0001-git-subtree-Use-gitexecdir-instead-of-libexecdir.patch # This fixes the build when python is enabled. Needs discussion upstream to # find a proper solution. Patch6: 0001-Drop-DESTDIR-from-python-instlibdir.patch +Patch7: 0001-submodule-allow-only-certain-protocols-for-submodule.patch +Patch8: 0002-transport-add-a-protocol-whitelist-environment-varia.patch +Patch9: 0003-transport-refactor-protocol-whitelist-code.patch +Patch10: 0004-http-limit-redirection-to-protocol-whitelist.patch +Patch11: 0005-http-limit-redirection-depth.patch +# CVE-2016-2315 / CVE-2016-2324 +Patch12: 0001-Fix-CVE-2016-2315-CVE-2016-2324.patch +# CVE-2014-9938 +Patch13: 0007-git-prompt.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -273,6 +282,13 @@ Requires: emacs-git = %{version}-%{release} %endif %patch5 -p1 %patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 %if %{use_prebuilt_docs} mkdir -p prebuilt_docs/{html,man} @@ -564,6 +580,18 @@ rm -rf %{buildroot} # No files for you! %changelog +* Wed Mar 29 2017 Petr Stodulka - 1.8.2.3-2 +- do not put unsanitized branch names in $PS1 + Resolves: CVE-2014-9938 + +* Mon Apr 18 2016 Todd Zullinger - 1.8.2.3-1 +- Update to 1.8.2.3 +- Apply Petr's fix for CVE-2016-2315 CVE-2016-2324 from el6 (#1318252) + +* Sun Nov 01 2015 Petr Stodulka - 1.8.2.1-2 +- fix arbitrary code execution via crafted URLs + Resolves: #1269798 + * Sun Apr 14 2013 Todd Zullinger - 1.8.2.1-1 - Update to 1.8.2.1 - Exclude optional perl(YAML::Any) dependency on EL-5 diff --git a/sources b/sources index b8e9dd0..19edaf6 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -3f6ebca116c627490e4ee1f1324d5e65 git-1.8.2.1.tar.gz -e53c46eca9e5f5da8fde35e1edc1d00b git-htmldocs-1.8.2.1.tar.gz -8ec6ab4d8c868305e9a679f5c3d2ccfa git-manpages-1.8.2.1.tar.gz +c529f6d4f1bf01fb919cb576c0dd58ae git-1.8.2.3.tar.xz +c4e9d1c84880ae60dcc32e140cfba2d2 git-htmldocs-1.8.2.3.tar.gz +891481ec6ecd9ee530701378e5b61d3f git-manpages-1.8.2.3.tar.gz