X-Original-To: alpine-aports@lists.alpinelinux.org Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by lists.alpinelinux.org (Postfix) with ESMTP id 4DF135C45B2 for ; Thu, 15 Dec 2016 14:43:14 +0000 (GMT) Received: by mail-wm0-f68.google.com with SMTP id a20so6944051wme.2 for ; Thu, 15 Dec 2016 06:43:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=Ok8/+gYBI3dk7uDFsseZ1N50zkNQROxPwIIKjLAH7Jc=; b=vU5tKp+IGHHEwrYd8ivqjS/tJanjKXY+GJAAyjm3zKe9ycYkFq5r4l4RDmcobzNd22 ft1TgSb8/yk00ngIOFE7Vy/hrQgSZIGqcGPWX2z/4TQNOP1yqJF7Q8TuDfh+D9rX8bR6 kCh2L/xNxyvOA0Szm/scTo7EAO9miB7mSYZDvM5roRCWnOUEyAmp7a+aD8QtbmymyvIO jtTJFb/Q3jav11bFniNktt3fWV2gVQHdbKARcr8bWXLjzoTyaB0IHt3Hod0ghnPWkDGc roAzjN1q/wGDv8jZv0+xOSVwx7HHVe9zLPL2Amb8hTGfO9MBRrjG4d4lmgNArDkMXBmS 07qg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Ok8/+gYBI3dk7uDFsseZ1N50zkNQROxPwIIKjLAH7Jc=; b=At/Oo1fKM05YoWg7eBhaGcJwl/TaZekEyBTUOzqUsWYYHhCHdMuZPqgUScKcpScmWx 6DTN/594Ukgh7wpI+YOTnnsy7m6ggF+KKLtdJtBPV6L2veJgZd0IW/EapOcYdNAHoJn6 WVzrxbKCbb5O2wPNRxraweIPKYJh5uStMX4rKzLjEyvzK1XOjdG6jYlhMW+heytuRNZn AAMzk/HkICV6Nt6u3mwbA8M7F1Gx0DWrZvtoNg3re30iCqb5uW5dVH8knG41n9VjbzUw Y5HL0b4Sos7Tzaxqmw8qh3hegymPFzBQnKj4OvhM2pNB88sw9cEys1F7UX8ZyuT6InFQ AUrQ== X-Gm-Message-State: AKaTC00YWJmuJc0J2JxZP6BbwGokp6aXigtyi3zDzpRhcsDhd+ofgxX6L+xvhwE+3YXrPw== X-Received: by 10.25.212.82 with SMTP id l79mr548408lfg.155.1481812993099; Thu, 15 Dec 2016 06:43:13 -0800 (PST) Received: from v3-1.util.wtbts.net ([83.145.235.199]) by smtp.gmail.com with ESMTPSA id c78sm509259lfc.39.2016.12.15.06.43.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 15 Dec 2016 06:43:12 -0800 (PST) From: Sergey Lukin To: alpine-aports@lists.alpinelinux.org Cc: Sergey Lukin Subject: [alpine-aports] [PATCH v3.1] main/git: security upgrade - fixes #5005 Date: Thu, 15 Dec 2016 14:43:04 +0000 Message-Id: <1481812984-12782-1-git-send-email-sergej.lukin@gmail.com> X-Mailer: git-send-email 2.2.1 X-Mailinglist: alpine-aports Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: CVE-2015-7545 --- main/git/APKBUILD | 29 ++- main/git/CVE-2015-7545-patch1.patch | 427 ++++++++++++++++++++++++++++++++++++ main/git/CVE-2015-7545-patch2.patch | 100 +++++++++ main/git/CVE-2015-7545-patch3.patch | 101 +++++++++ main/git/CVE-2015-7545-patch4.patch | 135 ++++++++++++ main/git/CVE-2015-7545-patch5.patch | 57 +++++ 6 files changed, 845 insertions(+), 4 deletions(-) create mode 100644 main/git/CVE-2015-7545-patch1.patch create mode 100644 main/git/CVE-2015-7545-patch2.patch create mode 100644 main/git/CVE-2015-7545-patch3.patch create mode 100644 main/git/CVE-2015-7545-patch4.patch create mode 100644 main/git/CVE-2015-7545-patch5.patch diff --git a/main/git/APKBUILD b/main/git/APKBUILD index 37299ed..2fec308 100644 --- a/main/git/APKBUILD +++ b/main/git/APKBUILD @@ -1,7 +1,8 @@ # Maintainer: Natanael Copa +# Contributor: Sergey Lukin pkgname=git pkgver=2.2.1 -pkgrel=0 +pkgrel=1 pkgdesc="A distributed version control system" url="http://git.or.cz/" arch="all" @@ -31,6 +32,11 @@ source="git-$pkgver.tar.gz::https://github.com/git/git/archive/v$pkgver.tar.gz bb-tar.patch git-daemon.initd git-daemon.confd + CVE-2015-7545-patch1.patch + CVE-2015-7545-patch2.patch + CVE-2015-7545-patch3.patch + CVE-2015-7545-patch4.patch + CVE-2015-7545-patch5.patch " _makeopts=" @@ -203,12 +209,27 @@ _git_perl() { md5sums="d1110e35369bc37aa204915f64c5d1c8 git-2.2.1.tar.gz e63a201556c4f089de790805c09a2e5b bb-tar.patch 53546650670c0ab8858e91474e5ffee9 git-daemon.initd -2258e95d389ccc6de0b5111d53d9eed6 git-daemon.confd" +2258e95d389ccc6de0b5111d53d9eed6 git-daemon.confd +33f105ea489d55f9cece57deed8a27bd CVE-2015-7545-patch1.patch +2e666466fb83c3b9af065142d410408f CVE-2015-7545-patch2.patch +08199293b22e258492f3f35ff1245c22 CVE-2015-7545-patch3.patch +84af0023dff4e7f5cbd9da708a296e90 CVE-2015-7545-patch4.patch +0c8c2b7f681c335d405aeedf9f8401e6 CVE-2015-7545-patch5.patch" sha256sums="aca76e204d2ad3ea783f5309261dc5fcadbd7a996afd841bdb7bf4a29658c067 git-2.2.1.tar.gz cb6319f47d81605e199771350154cbed0a6e85ef9042a689f2b405c64039f49c bb-tar.patch 817cd58dcb9a5ff32759d2132bb805a5dd34ad6fa0b0a5cbe4ab8786f3b7c0d9 git-daemon.initd -aaa80bd059db549dadf4c4e27a9aa41a4b5def844f8e563c493bc8513dcd981e git-daemon.confd" +aaa80bd059db549dadf4c4e27a9aa41a4b5def844f8e563c493bc8513dcd981e git-daemon.confd +aeae9d25df30a59e15f30c6047bb627de120cab1c724558140941514ae782229 CVE-2015-7545-patch1.patch +d34690d72179773a6b1769ea3a85ab91d17e7ba6f38abec683d911c598dd12fb CVE-2015-7545-patch2.patch +ab5a8070e6c47bb6d7d553c3f7f12e864490b6cd139b2e03e04b9cffac7bd358 CVE-2015-7545-patch3.patch +cf75d74b185fa2bf5bcfd33764ea6cd6ec66a072182def4d34493a4a4b69d1ed CVE-2015-7545-patch4.patch +2f23f815b4508edf1f39293de31b2874b1702fe79f3b45954bd2125b9fb2131a CVE-2015-7545-patch5.patch" sha512sums="b723dff750b8fad34b7268158c74f17a403ebc4358944b0c2986922090366e87840d6d3bd14b4574f63157acd1b69799715fbbe7decd70fa4edc18b1584a8ae8 git-2.2.1.tar.gz 6fa088a753c2a697e8dbef2032ed63e8c2a0553a41cff2fcff893c2f35c51d2c697054cc921c23ee606f77b93d0f340df85220b15e1c470bd352f7fba3986cd0 bb-tar.patch 47f35d1553408236502f936d0ce5dbc6c44b6593ad5ef9ddebbfd8dbca5f968c21452df7053ac271445830d36a147a7124e2ea1cf9fb98340d975fdb0346011a git-daemon.initd -9640f8078d68ed2678e5249da3f946fc21f50e858b94127a4221de73c6132101afcd46bc1fe33861e9a7f731c0dc9591915b8ebf376b8e690cd7135703966509 git-daemon.confd" +9640f8078d68ed2678e5249da3f946fc21f50e858b94127a4221de73c6132101afcd46bc1fe33861e9a7f731c0dc9591915b8ebf376b8e690cd7135703966509 git-daemon.confd +f1db673f02a685cc27c8272bf5debe912e1a46fce49196f946df84678f778939f5789c6964c9fb74f2f604ebf8f51a3b9e859a6e26818110febef4413697b8c0 CVE-2015-7545-patch1.patch +ec985321aa9aa7bc157f965f2f40c622855578c6e25fa7f05cf1e865820b22b6a159751c1cf8591226a3de35476d1df0275ae468d93e0c6d3db2447f4820f2ed CVE-2015-7545-patch2.patch +8a0b6ee85c33fc6012afd4b7677f698423ddf7a4e97c0008af288d716bc884f28f057e7ea000e548311699a779b7b84c3c6ab792f9f8ebc91c99d01691b25cde CVE-2015-7545-patch3.patch +07d474f08dd338a7a36dff84274973f49350724d422aa3e5f2cb192a4d6bbd942176567623580a8dcfc309a3c656f6838303fd6aae0820173ee989c98114904e CVE-2015-7545-patch4.patch +feb4be2594cca6a9fc34633fca75389bfbf6230e22d697b54c2c02d24586407d717b9173ad5942d3e9652c7c3dc14c3d6cf08d33ed26d0e94cd46c06bd28be96 CVE-2015-7545-patch5.patch" diff --git a/main/git/CVE-2015-7545-patch1.patch b/main/git/CVE-2015-7545-patch1.patch new file mode 100644 index 0000000..4cf9483 --- /dev/null +++ b/main/git/CVE-2015-7545-patch1.patch @@ -0,0 +1,427 @@ +commit a5adaced2e13c135d5d9cc65be9eb95aa3bacedf +Author: Jeff King +Date: Wed Sep 16 13:12:52 2015 -0400 + + 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. + + Signed-off-by: Jeff King + Signed-off-by: Junio C Hamano + +diff --git a/Documentation/git.txt b/Documentation/git.txt +index a62ed6f..b6a12b3 100644 +--- a/Documentation/git.txt ++++ b/Documentation/git.txt +@@ -1045,6 +1045,38 @@ GIT_ICASE_PATHSPECS:: + an operation has touched every ref (e.g., because you are + cloning a repository to make a backup). + ++`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 14c924b..bd4b50e 100644 +--- a/connect.c ++++ b/connect.c +@@ -9,6 +9,7 @@ + #include "url.h" + #include "string-list.h" + #include "sha1-array.h" ++#include "transport.h" + + static char *server_capabilities; + static const char *parse_feature_value(const char *, const char *, int *); +@@ -694,6 +695,9 @@ struct child_process *git_connect(int fd[2], const char *url, + * cannot connect. + */ + char *target_host = xstrdup(hostandport); ++ ++ transport_check_allowed("git"); ++ + if (git_use_proxy(hostandport)) + conn = git_proxy_connect(fd, hostandport); + else +@@ -727,6 +730,7 @@ struct child_process *git_connect(int fd[2], const char *url, + int putty; + char *ssh_host = hostandport; + const char *port = NULL; ++ transport_check_allowed("ssh"); + get_host_and_port(&ssh_host, &port); + + if (!port) +@@ -768,6 +772,7 @@ struct child_process *git_connect(int fd[2], const char *url, + /* remove repo-local variables from the environment */ + conn->env = local_repo_env; + conn->use_shell = 1; ++ transport_check_allowed("file"); + } + argv_array_push(&conn->args, cmd.buf); + +diff --git a/t/lib-proto-disable.sh b/t/lib-proto-disable.sh +new file mode 100644 +index 0000000..b0917d9 +--- /dev/null ++++ b/t/lib-proto-disable.sh +@@ -0,0 +1,96 @@ ++# Test routines for checking protocol disabling. ++ ++# test cloning a particular protocol ++# $1 - description of the protocol ++# $2 - machine-readable name of the protocol ++# $3 - the URL to try cloning ++test_proto () { ++ desc=$1 ++ proto=$2 ++ url=$3 ++ ++ test_expect_success "clone $1 (enabled)" ' ++ rm -rf tmp.git && ++ ( ++ GIT_ALLOW_PROTOCOL=$proto && ++ export GIT_ALLOW_PROTOCOL && ++ git clone --bare "$url" tmp.git ++ ) ++ ' ++ ++ test_expect_success "fetch $1 (enabled)" ' ++ ( ++ cd tmp.git && ++ GIT_ALLOW_PROTOCOL=$proto && ++ export GIT_ALLOW_PROTOCOL && ++ git fetch ++ ) ++ ' ++ ++ test_expect_success "push $1 (enabled)" ' ++ ( ++ cd tmp.git && ++ GIT_ALLOW_PROTOCOL=$proto && ++ export GIT_ALLOW_PROTOCOL && ++ git push origin HEAD:pushed ++ ) ++ ' ++ ++ test_expect_success "push $1 (disabled)" ' ++ ( ++ cd tmp.git && ++ GIT_ALLOW_PROTOCOL=none && ++ export GIT_ALLOW_PROTOCOL && ++ test_must_fail git push origin HEAD:pushed ++ ) ++ ' ++ ++ test_expect_success "fetch $1 (disabled)" ' ++ ( ++ cd tmp.git && ++ GIT_ALLOW_PROTOCOL=none && ++ export GIT_ALLOW_PROTOCOL && ++ test_must_fail git fetch ++ ) ++ ' ++ ++ test_expect_success "clone $1 (disabled)" ' ++ rm -rf tmp.git && ++ ( ++ GIT_ALLOW_PROTOCOL=none && ++ export GIT_ALLOW_PROTOCOL && ++ test_must_fail git clone --bare "$url" tmp.git ++ ) ++ ' ++} ++ ++# set up an ssh wrapper that will access $host/$repo in the ++# trash directory, and enable it for subsequent tests. ++setup_ssh_wrapper () { ++ test_expect_success 'setup ssh wrapper' ' ++ write_script ssh-wrapper <<-\EOF && ++ echo >&2 "ssh: $*" ++ host=$1; shift ++ cd "$TRASH_DIRECTORY/$host" && ++ eval "$*" ++ EOF ++ GIT_SSH="$PWD/ssh-wrapper" && ++ export GIT_SSH && ++ export TRASH_DIRECTORY ++ ' ++} ++ ++# set up a wrapper that can be used with remote-ext to ++# access repositories in the "remote" directory of trash-dir, ++# like "ext::fake-remote %S repo.git" ++setup_ext_wrapper () { ++ test_expect_success 'setup ext wrapper' ' ++ write_script fake-remote <<-\EOF && ++ echo >&2 "fake-remote: $*" ++ cd "$TRASH_DIRECTORY/remote" && ++ eval "$*" ++ EOF ++ PATH=$TRASH_DIRECTORY:$PATH && ++ export TRASH_DIRECTORY ++ ' ++} +diff --git a/t/t5810-proto-disable-local.sh b/t/t5810-proto-disable-local.sh +new file mode 100755 +index 0000000..563592d +--- /dev/null ++++ b/t/t5810-proto-disable-local.sh +@@ -0,0 +1,14 @@ ++#!/bin/sh ++ ++test_description='test disabling of local paths in clone/fetch' ++. ./test-lib.sh ++. "$TEST_DIRECTORY/lib-proto-disable.sh" ++ ++test_expect_success 'setup repository to clone' ' ++ test_commit one ++' ++ ++test_proto "file://" file "file://$PWD" ++test_proto "path" file . ++ ++test_done +diff --git a/t/t5811-proto-disable-git.sh b/t/t5811-proto-disable-git.sh +new file mode 100755 +index 0000000..8ac6b2a +--- /dev/null ++++ b/t/t5811-proto-disable-git.sh +@@ -0,0 +1,20 @@ ++#!/bin/sh ++ ++test_description='test disabling of git-over-tcp in clone/fetch' ++. ./test-lib.sh ++. "$TEST_DIRECTORY/lib-proto-disable.sh" ++. "$TEST_DIRECTORY/lib-git-daemon.sh" ++start_git_daemon ++ ++test_expect_success 'create git-accessible repo' ' ++ bare="$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" && ++ test_commit one && ++ git --bare init "$bare" && ++ git push "$bare" HEAD && ++ >"$bare/git-daemon-export-ok" && ++ git -C "$bare" config daemon.receivepack true ++' ++ ++test_proto "git://" git "$GIT_DAEMON_URL/repo.git" ++ ++test_done +diff --git a/t/t5812-proto-disable-http.sh b/t/t5812-proto-disable-http.sh +new file mode 100755 +index 0000000..dd5001c +--- /dev/null ++++ b/t/t5812-proto-disable-http.sh +@@ -0,0 +1,20 @@ ++#!/bin/sh ++ ++test_description='test disabling of git-over-http in clone/fetch' ++. ./test-lib.sh ++. "$TEST_DIRECTORY/lib-proto-disable.sh" ++. "$TEST_DIRECTORY/lib-httpd.sh" ++start_httpd ++ ++test_expect_success 'create git-accessible repo' ' ++ bare="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && ++ test_commit one && ++ git --bare init "$bare" && ++ git push "$bare" HEAD && ++ git -C "$bare" config http.receivepack true ++' ++ ++test_proto "smart http" http "$HTTPD_URL/smart/repo.git" ++ ++stop_httpd ++test_done +diff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh +new file mode 100755 +index 0000000..ad877d7 +--- /dev/null ++++ b/t/t5813-proto-disable-ssh.sh +@@ -0,0 +1,20 @@ ++#!/bin/sh ++ ++test_description='test disabling of git-over-ssh in clone/fetch' ++. ./test-lib.sh ++. "$TEST_DIRECTORY/lib-proto-disable.sh" ++ ++setup_ssh_wrapper ++ ++test_expect_success 'setup repository to clone' ' ++ test_commit one && ++ mkdir remote && ++ git init --bare remote/repo.git && ++ git push remote/repo.git HEAD ++' ++ ++test_proto "host:path" ssh "remote:repo.git" ++test_proto "ssh://" ssh "ssh://remote/$PWD/remote/repo.git" ++test_proto "git+ssh://" ssh "git+ssh://remote/$PWD/remote/repo.git" ++ ++test_done +diff --git a/t/t5814-proto-disable-ext.sh b/t/t5814-proto-disable-ext.sh +new file mode 100755 +index 0000000..9d6f7df +--- /dev/null ++++ b/t/t5814-proto-disable-ext.sh +@@ -0,0 +1,18 @@ ++#!/bin/sh ++ ++test_description='test disabling of remote-helper paths in clone/fetch' ++. ./test-lib.sh ++. "$TEST_DIRECTORY/lib-proto-disable.sh" ++ ++setup_ext_wrapper ++ ++test_expect_success 'setup repository to clone' ' ++ test_commit one && ++ mkdir remote && ++ git init --bare remote/repo.git && ++ git push remote/repo.git HEAD ++' ++ ++test_proto "remote-helper" ext "ext::fake-remote %S repo.git" ++ ++test_done +diff --git a/transport-helper.c b/transport-helper.c +index 7dc4a44..0b5362c 100644 +--- a/transport-helper.c ++++ b/transport-helper.c +@@ -1038,6 +1038,8 @@ int transport_helper_init(struct transport *transport, const char *name) + struct helper_data *data = xcalloc(1, sizeof(*data)); + data->name = name; + ++ transport_check_allowed(name); ++ + if (getenv("GIT_TRANSPORT_HELPER_DEBUG")) + debug = 1; + +diff --git a/transport.c b/transport.c +index 88bde1d..94fe865 100644 +--- a/transport.c ++++ b/transport.c +@@ -909,6 +909,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; +@@ -940,12 +954,14 @@ struct transport *transport_get(struct remote *remote, const char *url) + if (helper) { + transport_helper_init(ret, helper); + } else if (starts_with(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 (url_is_local_not_ssh(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; +@@ -957,7 +973,10 @@ struct transport *transport_get(struct remote *remote, const char *url) + || starts_with(url, "ssh://") + || starts_with(url, "git+ssh://") + || starts_with(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 3e0091e..f7df6ec 100644 +--- a/transport.h ++++ b/transport.h +@@ -132,6 +132,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 */ diff --git a/main/git/CVE-2015-7545-patch2.patch b/main/git/CVE-2015-7545-patch2.patch new file mode 100644 index 0000000..7a6be12 --- /dev/null +++ b/main/git/CVE-2015-7545-patch2.patch @@ -0,0 +1,100 @@ +commit 33cfccbbf35a56e190b79bdec5c85457c952a021 +Author: Jeff King +Date: Wed Sep 16 13:13:12 2015 -0400 + + 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. + + Reported-by: Blake Burkhart + Signed-off-by: Jeff King + Signed-off-by: Junio C Hamano + +diff --git a/git-submodule.sh b/git-submodule.sh +index 36797c3..78c2740 100755 +--- a/git-submodule.sh ++++ b/git-submodule.sh +@@ -22,6 +22,15 @@ require_work_tree + wt_prefix=$(git rev-parse --show-prefix) + cd_to_toplevel + ++# 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 100755 +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 diff --git a/main/git/CVE-2015-7545-patch3.patch b/main/git/CVE-2015-7545-patch3.patch new file mode 100644 index 0000000..2df1fdd --- /dev/null +++ b/main/git/CVE-2015-7545-patch3.patch @@ -0,0 +1,101 @@ +commit 5088d3b38775f8ac12d7f77636775b16059b67ef +Author: Jeff King +Date: Tue Sep 22 18:03:49 2015 -0400 + + 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 + +diff --git a/transport.c b/transport.c +index 94fe865..647d2c2 100644 +--- a/transport.c ++++ b/transport.c +@@ -909,18 +909,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 f7df6ec..ed84da2 100644 +--- a/transport.h ++++ b/transport.h +@@ -133,12 +133,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 */ diff --git a/main/git/CVE-2015-7545-patch4.patch b/main/git/CVE-2015-7545-patch4.patch new file mode 100644 index 0000000..8e76516 --- /dev/null +++ b/main/git/CVE-2015-7545-patch4.patch @@ -0,0 +1,135 @@ +commit f4113cac0c88b4f36ee6f3abf3218034440a68e3 +Author: Blake Burkhart +Date: Tue Sep 22 18:06:04 2015 -0400 + + 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. + + This commit includes a test, but it is not as robust as we + would hope. It redirects an http request to ftp, and checks + that curl complained about the protocol, which means that we + are relying on curl's specific error message to know what + happened. Ideally we would redirect to a working ftp server + and confirm that we can clone without protocol restrictions, + and not with them. But we do not have a portable way of + providing an ftp server, nor any other protocol that curl + supports (https is the closest, but we would have to deal + with certificates). + + [jk: added test and version warning] + + Signed-off-by: Jeff King + Signed-off-by: Junio C Hamano + +diff --git a/Documentation/git.txt b/Documentation/git.txt +index b6a12b3..41a09ca 100644 +--- a/Documentation/git.txt ++++ b/Documentation/git.txt +@@ -1071,11 +1071,6 @@ GIT_ICASE_PATHSPECS:: + + - 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/http.c b/http.c +index 6798620..5a57bcc 100644 +--- a/http.c ++++ b/http.c +@@ -8,6 +8,7 @@ + #include "credential.h" + #include "version.h" + #include "pkt-line.h" ++#include "transport.h" + + int active_requests; + int http_is_verbose; +@@ -303,6 +304,7 @@ static void set_curl_keepalive(CURL *c) + static CURL *get_curl_handle(void) + { + CURL *result = curl_easy_init(); ++ long allowed_protocols = 0; + + if (!result) + die("curl_easy_init failed"); +@@ -355,6 +357,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); +diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf +index 0b81a00..68ef8ad 100644 +--- a/t/lib-httpd/apache.conf ++++ b/t/lib-httpd/apache.conf +@@ -119,6 +119,7 @@ RewriteRule ^/smart-redir-perm/(.*)$ /smart/$1 [R=301] + RewriteRule ^/smart-redir-temp/(.*)$ /smart/$1 [R=302] + RewriteRule ^/smart-redir-auth/(.*)$ /auth/smart/$1 [R=301] + RewriteRule ^/smart-redir-limited/(.*)/info/refs$ /smart/$1/info/refs [R=301] ++RewriteRule ^/ftp-redir/(.*)$ ftp://localhost:1000/$1 [R=302] + + + LoadModule ssl_module modules/mod_ssl.so +diff --git a/t/t5812-proto-disable-http.sh b/t/t5812-proto-disable-http.sh +index dd5001c..6a4f816 100755 +--- a/t/t5812-proto-disable-http.sh ++++ b/t/t5812-proto-disable-http.sh +@@ -16,5 +16,14 @@ test_expect_success 'create git-accessible repo' ' + + test_proto "smart http" http "$HTTPD_URL/smart/repo.git" + ++test_expect_success 'curl redirects respect whitelist' ' ++ test_must_fail env GIT_ALLOW_PROTOCOL=http:https \ ++ git clone "$HTTPD_URL/ftp-redir/repo.git" 2>stderr && ++ { ++ test_i18ngrep "ftp.*disabled" stderr || ++ test_i18ngrep "your curl version is too old" ++ } ++' ++ + stop_httpd + test_done diff --git a/main/git/CVE-2015-7545-patch5.patch b/main/git/CVE-2015-7545-patch5.patch new file mode 100644 index 0000000..8845540 --- /dev/null +++ b/main/git/CVE-2015-7545-patch5.patch @@ -0,0 +1,57 @@ +commit b258116462399b318c86165c61a5c7123043cfd4 +Author: Blake Burkhart +Date: Tue Sep 22 18:06:20 2015 -0400 + + 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. + + Signed-off-by: Jeff King + Signed-off-by: Junio C Hamano + +diff --git a/http.c b/http.c +index 5a57bcc..00e3fc8 100644 +--- a/http.c ++++ b/http.c +@@ -352,6 +352,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 +diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf +index 68ef8ad..7d15e6d 100644 +--- a/t/lib-httpd/apache.conf ++++ b/t/lib-httpd/apache.conf +@@ -121,6 +121,9 @@ RewriteRule ^/smart-redir-auth/(.*)$ /auth/smart/$1 [R=301] + RewriteRule ^/smart-redir-limited/(.*)/info/refs$ /smart/$1/info/refs [R=301] + RewriteRule ^/ftp-redir/(.*)$ ftp://localhost:1000/$1 [R=302] + ++RewriteRule ^/loop-redir/x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-(.*) /$1 [R=302] ++RewriteRule ^/loop-redir/(.*)$ /loop-redir/x-$1 [R=302] ++ + + LoadModule ssl_module modules/mod_ssl.so + +diff --git a/t/t5812-proto-disable-http.sh b/t/t5812-proto-disable-http.sh +index 6a4f816..0d105d5 100755 +--- a/t/t5812-proto-disable-http.sh ++++ b/t/t5812-proto-disable-http.sh +@@ -25,5 +25,9 @@ test_expect_success 'curl redirects respect whitelist' ' + } + ' + ++test_expect_success 'curl limits redirects' ' ++ test_must_fail git clone "$HTTPD_URL/loop-redir/smart/repo.git" ++' ++ + stop_httpd + test_done -- 2.2.1 --- Unsubscribe: alpine-aports+unsubscribe@lists.alpinelinux.org Help: alpine-aports+help@lists.alpinelinux.org ---