Compare commits
28 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5e5a352fe | ||
|
|
8478810fb2 | ||
|
|
94ab29eacc | ||
|
|
863e09f0e0 | ||
|
|
81a4c6c16d | ||
|
|
bbd216e6ea | ||
|
|
c847a30642 | ||
|
|
c2f736a3e8 | ||
|
|
638c6f27b7 | ||
|
|
6272f498c4 | ||
|
|
47f75306db | ||
|
|
b81bad80b8 | ||
|
|
68dadc6a17 | ||
|
|
f359a5552b | ||
|
|
933bdd1abf | ||
|
|
00e8ae1130 | ||
|
|
96186fa43d | ||
|
|
4dbe084001 | ||
|
|
21d9c2a3c6 | ||
|
|
c8d6dbdf8b | ||
|
|
45d5187933 | ||
|
|
4a3c677a3b | ||
|
|
3888ddcd60 | ||
|
|
f41afabc13 | ||
|
|
8a8a31c445 | ||
|
|
608e8bdbf4 | ||
|
|
9a8286927a | ||
|
|
73f81376f9 |
10 changed files with 732 additions and 8 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,5 +1,6 @@
|
|||
*~
|
||||
*.rpm
|
||||
*.tar.gz
|
||||
*.tar.xz
|
||||
/.build*.log
|
||||
/git-*/
|
||||
|
|
|
|||
116
0001-Fix-CVE-2016-2315-CVE-2016-2324.patch
Normal file
116
0001-Fix-CVE-2016-2315-CVE-2016-2324.patch
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
From 5857966a36f9c553e73e375455a246896aeba73f Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
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
|
||||
|
||||
104
0001-submodule-allow-only-certain-protocols-for-submodule.patch
Normal file
104
0001-submodule-allow-only-certain-protocols-for-submodule.patch
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
From 6d69680505dbbc484178105815ed624fab40b2de Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
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
|
||||
|
||||
207
0002-transport-add-a-protocol-whitelist-environment-varia.patch
Normal file
207
0002-transport-add-a-protocol-whitelist-environment-varia.patch
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
From cfa4e13f09d07f679ffacdddfbe0ef44d1de32d9 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
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
|
||||
|
||||
107
0003-transport-refactor-protocol-whitelist-code.patch
Normal file
107
0003-transport-refactor-protocol-whitelist-code.patch
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
From 9b9aabe6ab5d07227c1c02781f03a3c38fbc27b0 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff King <peff@peff.net>
|
||||
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 <bburky@bburky.com>
|
||||
Signed-off-by: Jeff King <peff@peff.net>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
---
|
||||
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
|
||||
|
||||
77
0004-http-limit-redirection-to-protocol-whitelist.patch
Normal file
77
0004-http-limit-redirection-to-protocol-whitelist.patch
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
From 0f032880eddc09abd1850533422c9b0bb80a010c Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
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
|
||||
|
||||
31
0005-http-limit-redirection-depth.patch
Normal file
31
0005-http-limit-redirection-depth.patch
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
From 7f3bfdbc2670b4960242fa1b229dde6bcb2b463b Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
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
|
||||
|
||||
53
0007-git-prompt.patch
Normal file
53
0007-git-prompt.patch
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
From 7e546ae76da784185ba9515ed86e435ba17fdd65 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
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
|
||||
|
||||
38
git.spec
38
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 <pstodulk@redhat.com> - 1.8.2.3-2
|
||||
- do not put unsanitized branch names in $PS1
|
||||
Resolves: CVE-2014-9938
|
||||
|
||||
* Mon Apr 18 2016 Todd Zullinger <tmz@pobox.com> - 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 <pstodulk@redhat.com> - 1.8.2.1-2
|
||||
- fix arbitrary code execution via crafted URLs
|
||||
Resolves: #1269798
|
||||
|
||||
* Sun Apr 14 2013 Todd Zullinger <tmz@pobox.com> - 1.8.2.1-1
|
||||
- Update to 1.8.2.1
|
||||
- Exclude optional perl(YAML::Any) dependency on EL-5
|
||||
|
|
|
|||
6
sources
6
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue