Skip to content

Commit 6343e2f

Browse files
committed
Sync with 2.3.10
2 parents 74b6763 + 18b58f7 commit 6343e2f

27 files changed

+446
-28
lines changed

Documentation/RelNotes/2.3.10.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Git v2.3.10 Release Notes
2+
=========================
3+
4+
Fixes since v2.3.9
5+
------------------
6+
7+
* xdiff code we use to generate diffs is not prepared to handle
8+
extremely large files. It uses "int" in many places, which can
9+
overflow if we have a very large number of lines or even bytes in
10+
our input files, for example. Cap the input size to soemwhere
11+
around 1GB for now.
12+
13+
* Some protocols (like git-remote-ext) can execute arbitrary code
14+
found in the URL. The URLs that submodules use may come from
15+
arbitrary sources (e.g., .gitmodules files in a remote
16+
repository), and can hurt those who blindly enable recursive
17+
fetch. Restrict the allowed protocols to well known and safe
18+
ones.

Documentation/git.txt

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ Documentation for older releases are available here:
5757
link:RelNotes/2.4.1.txt[2.4.1],
5858
link:RelNotes/2.4.0.txt[2.4].
5959

60-
* link:v2.3.9/git.html[documentation for release 2.3.9]
60+
* link:v2.3.10/git.html[documentation for release 2.3.10]
6161

6262
* release notes for
63+
link:RelNotes/2.3.10.txt[2.3.10],
6364
link:RelNotes/2.3.9.txt[2.3.9],
6465
link:RelNotes/2.3.8.txt[2.3.8],
6566
link:RelNotes/2.3.7.txt[2.3.7],
@@ -1059,6 +1060,33 @@ GIT_ICASE_PATHSPECS::
10591060
an operation has touched every ref (e.g., because you are
10601061
cloning a repository to make a backup).
10611062

1063+
`GIT_ALLOW_PROTOCOL`::
1064+
If set, provide a colon-separated list of protocols which are
1065+
allowed to be used with fetch/push/clone. This is useful to
1066+
restrict recursive submodule initialization from an untrusted
1067+
repository. Any protocol not mentioned will be disallowed (i.e.,
1068+
this is a whitelist, not a blacklist). If the variable is not
1069+
set at all, all protocols are enabled. The protocol names
1070+
currently used by git are:
1071+
1072+
- `file`: any local file-based path (including `file://` URLs,
1073+
or local paths)
1074+
1075+
- `git`: the anonymous git protocol over a direct TCP
1076+
connection (or proxy, if configured)
1077+
1078+
- `ssh`: git over ssh (including `host:path` syntax,
1079+
`git+ssh://`, etc).
1080+
1081+
- `rsync`: git over rsync
1082+
1083+
- `http`: git over http, both "smart http" and "dumb http".
1084+
Note that this does _not_ include `https`; if you want both,
1085+
you should specify both as `http:https`.
1086+
1087+
- any external helpers are named by their protocol (e.g., use
1088+
`hg` to allow the `git-remote-hg` helper)
1089+
10621090

10631091
Discussion[[Discussion]]
10641092
------------------------

builtin/blame.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,10 @@ static void pass_blame_to_parent(struct scoreboard *sb,
973973
fill_origin_blob(&sb->revs->diffopt, target, &file_o);
974974
num_get_patch++;
975975

976-
diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d);
976+
if (diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d))
977+
die("unable to generate diff (%s -> %s)",
978+
sha1_to_hex(parent->commit->object.sha1),
979+
sha1_to_hex(target->commit->object.sha1));
977980
/* The rest are the same as the parent */
978981
blame_chunk(&d.dstq, &d.srcq, INT_MAX, d.offset, INT_MAX, parent);
979982
*d.dstq = NULL;
@@ -1119,7 +1122,9 @@ static void find_copy_in_blob(struct scoreboard *sb,
11191122
* file_p partially may match that image.
11201123
*/
11211124
memset(split, 0, sizeof(struct blame_entry [3]));
1122-
diff_hunks(file_p, &file_o, 1, handle_split_cb, &d);
1125+
if (diff_hunks(file_p, &file_o, 1, handle_split_cb, &d))
1126+
die("unable to generate diff (%s)",
1127+
sha1_to_hex(parent->commit->object.sha1));
11231128
/* remainder, if any, all match the preimage */
11241129
handle_split(sb, ent, d.tlno, d.plno, ent->num_lines, parent, split);
11251130
}

builtin/merge-file.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
7575
names[i] = argv[i];
7676
if (read_mmfile(mmfs + i, fname))
7777
return -1;
78-
if (buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
78+
if (mmfs[i].size > MAX_XDIFF_SIZE ||
79+
buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
7980
return error("Cannot merge binary files: %s",
8081
argv[i]);
8182
}

builtin/merge-tree.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ static void show_diff(struct merge_list *entry)
118118
if (!dst.ptr)
119119
size = 0;
120120
dst.size = size;
121-
xdi_diff(&src, &dst, &xpp, &xecfg, &ecb);
121+
if (xdi_diff(&src, &dst, &xpp, &xecfg, &ecb))
122+
die("unable to generate diff");
122123
free(src.ptr);
123124
free(dst.ptr);
124125
}

builtin/rerere.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ static int diff_two(const char *file1, const char *label1,
2929
xdemitconf_t xecfg;
3030
xdemitcb_t ecb;
3131
mmfile_t minus, plus;
32+
int ret;
3233

3334
if (read_mmfile(&minus, file1) || read_mmfile(&plus, file2))
34-
return 1;
35+
return -1;
3536

3637
printf("--- a/%s\n+++ b/%s\n", label1, label2);
3738
fflush(stdout);
@@ -40,11 +41,11 @@ static int diff_two(const char *file1, const char *label1,
4041
memset(&xecfg, 0, sizeof(xecfg));
4142
xecfg.ctxlen = 3;
4243
ecb.outf = outf;
43-
xdi_diff(&minus, &plus, &xpp, &xecfg, &ecb);
44+
ret = xdi_diff(&minus, &plus, &xpp, &xecfg, &ecb);
4445

4546
free(minus.ptr);
4647
free(plus.ptr);
47-
return 0;
48+
return ret;
4849
}
4950

5051
int cmd_rerere(int argc, const char **argv, const char *prefix)
@@ -104,7 +105,8 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
104105
for (i = 0; i < merge_rr.nr; i++) {
105106
const char *path = merge_rr.items[i].string;
106107
const char *name = (const char *)merge_rr.items[i].util;
107-
diff_two(rerere_path(name, "preimage"), path, path, path);
108+
if (diff_two(rerere_path(name, "preimage"), path, path, path))
109+
die("unable to generate diff for %s", name);
108110
}
109111
else
110112
usage_with_options(rerere_usage, options);

combine-diff.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,10 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
419419
state.num_parent = num_parent;
420420
state.n = n;
421421

422-
xdi_diff_outf(&parent_file, result_file, consume_line, &state,
423-
&xpp, &xecfg);
422+
if (xdi_diff_outf(&parent_file, result_file, consume_line, &state,
423+
&xpp, &xecfg))
424+
die("unable to generate combined diff for %s",
425+
sha1_to_hex(parent));
424426
free(parent_file.ptr);
425427

426428
/* Assign line numbers for this parent.

connect.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "url.h"
1010
#include "string-list.h"
1111
#include "sha1-array.h"
12+
#include "transport.h"
1213

1314
static char *server_capabilities;
1415
static const char *parse_feature_value(const char *, const char *, int *);
@@ -694,6 +695,8 @@ struct child_process *git_connect(int fd[2], const char *url,
694695
else
695696
target_host = xstrdup(hostandport);
696697

698+
transport_check_allowed("git");
699+
697700
/* These underlying connection commands die() if they
698701
* cannot connect.
699702
*/
@@ -727,6 +730,7 @@ struct child_process *git_connect(int fd[2], const char *url,
727730
int putty, tortoiseplink = 0;
728731
char *ssh_host = hostandport;
729732
const char *port = NULL;
733+
transport_check_allowed("ssh");
730734
get_host_and_port(&ssh_host, &port);
731735

732736
if (!port)
@@ -781,6 +785,7 @@ struct child_process *git_connect(int fd[2], const char *url,
781785
/* remove repo-local variables from the environment */
782786
conn->env = local_repo_env;
783787
conn->use_shell = 1;
788+
transport_check_allowed("file");
784789
}
785790
argv_array_push(&conn->args, cmd.buf);
786791

diff.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,8 +1002,9 @@ static void diff_words_show(struct diff_words_data *diff_words)
10021002
xpp.flags = 0;
10031003
/* as only the hunk header will be parsed, we need a 0-context */
10041004
xecfg.ctxlen = 0;
1005-
xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, diff_words,
1006-
&xpp, &xecfg);
1005+
if (xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, diff_words,
1006+
&xpp, &xecfg))
1007+
die("unable to generate word diff");
10071008
free(minus.ptr);
10081009
free(plus.ptr);
10091010
if (diff_words->current_plus != diff_words->plus.text.ptr +
@@ -2400,8 +2401,9 @@ static void builtin_diff(const char *name_a,
24002401
xecfg.ctxlen = strtoul(v, NULL, 10);
24012402
if (o->word_diff)
24022403
init_diff_words_data(&ecbdata, o, one, two);
2403-
xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
2404-
&xpp, &xecfg);
2404+
if (xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
2405+
&xpp, &xecfg))
2406+
die("unable to generate diff for %s", one->path);
24052407
if (o->word_diff)
24062408
free_diff_words_data(&ecbdata);
24072409
if (textconv_one)
@@ -2478,8 +2480,9 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
24782480
xpp.flags = o->xdl_opts;
24792481
xecfg.ctxlen = o->context;
24802482
xecfg.interhunkctxlen = o->interhunkcontext;
2481-
xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
2482-
&xpp, &xecfg);
2483+
if (xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
2484+
&xpp, &xecfg))
2485+
die("unable to generate diffstat for %s", one->path);
24832486
}
24842487

24852488
diff_free_filespec_data(one);
@@ -2525,8 +2528,9 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
25252528
memset(&xecfg, 0, sizeof(xecfg));
25262529
xecfg.ctxlen = 1; /* at least one context line */
25272530
xpp.flags = 0;
2528-
xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
2529-
&xpp, &xecfg);
2531+
if (xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
2532+
&xpp, &xecfg))
2533+
die("unable to generate checkdiff for %s", one->path);
25302534

25312535
if (data.ws_rule & WS_BLANK_AT_EOF) {
25322536
struct emit_callback ecbdata;
@@ -4425,8 +4429,10 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1)
44254429
xpp.flags = 0;
44264430
xecfg.ctxlen = 3;
44274431
xecfg.flags = 0;
4428-
xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
4429-
&xpp, &xecfg);
4432+
if (xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
4433+
&xpp, &xecfg))
4434+
return error("unable to generate patch-id diff for %s",
4435+
p->one->path);
44304436
}
44314437

44324438
git_SHA1_Final(sha1, &ctx);

diffcore-pickaxe.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ static int diff_grep(mmfile_t *one, mmfile_t *two,
6262
ecbdata.hit = 0;
6363
xecfg.ctxlen = o->context;
6464
xecfg.interhunkctxlen = o->interhunkcontext;
65-
xdi_diff_outf(one, two, diffgrep_consume, &ecbdata,
66-
&xpp, &xecfg);
65+
if (xdi_diff_outf(one, two, diffgrep_consume, &ecbdata, &xpp, &xecfg))
66+
return 0;
6767
return ecbdata.hit;
6868
}
6969

git-submodule.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ require_work_tree
2222
wt_prefix=$(git rev-parse --show-prefix)
2323
cd_to_toplevel
2424

25+
# Restrict ourselves to a vanilla subset of protocols; the URLs
26+
# we get are under control of a remote repository, and we do not
27+
# want them kicking off arbitrary git-remote-* programs.
28+
#
29+
# If the user has already specified a set of allowed protocols,
30+
# we assume they know what they're doing and use that instead.
31+
: ${GIT_ALLOW_PROTOCOL=file:git:http:https:ssh}
32+
export GIT_ALLOW_PROTOCOL
33+
2534
command=
2635
branch=
2736
force=

http.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "version.h"
1010
#include "pkt-line.h"
1111
#include "gettext.h"
12+
#include "transport.h"
1213

1314
int active_requests;
1415
int http_is_verbose;
@@ -337,6 +338,7 @@ static void set_curl_keepalive(CURL *c)
337338
static CURL *get_curl_handle(void)
338339
{
339340
CURL *result = curl_easy_init();
341+
long allowed_protocols = 0;
340342

341343
if (!result)
342344
die("curl_easy_init failed");
@@ -384,11 +386,27 @@ static CURL *get_curl_handle(void)
384386
}
385387

386388
curl_easy_setopt(result, CURLOPT_FOLLOWLOCATION, 1);
389+
curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);
387390
#if LIBCURL_VERSION_NUM >= 0x071301
388391
curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
389392
#elif LIBCURL_VERSION_NUM >= 0x071101
390393
curl_easy_setopt(result, CURLOPT_POST301, 1);
391394
#endif
395+
#if LIBCURL_VERSION_NUM >= 0x071304
396+
if (is_transport_allowed("http"))
397+
allowed_protocols |= CURLPROTO_HTTP;
398+
if (is_transport_allowed("https"))
399+
allowed_protocols |= CURLPROTO_HTTPS;
400+
if (is_transport_allowed("ftp"))
401+
allowed_protocols |= CURLPROTO_FTP;
402+
if (is_transport_allowed("ftps"))
403+
allowed_protocols |= CURLPROTO_FTPS;
404+
curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS, allowed_protocols);
405+
#else
406+
if (transport_restrict_protocols())
407+
warning("protocol restrictions not applied to curl redirects because\n"
408+
"your curl version is too old (>= 7.19.4)");
409+
#endif
392410

393411
if (getenv("GIT_CURL_VERBOSE"))
394412
curl_easy_setopt(result, CURLOPT_VERBOSE, 1);

line-log.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ static int collect_diff_cb(long start_a, long count_a,
325325
return 0;
326326
}
327327

328-
static void collect_diff(mmfile_t *parent, mmfile_t *target, struct diff_ranges *out)
328+
static int collect_diff(mmfile_t *parent, mmfile_t *target, struct diff_ranges *out)
329329
{
330330
struct collect_diff_cbdata cbdata = {NULL};
331331
xpparam_t xpp;
@@ -340,7 +340,7 @@ static void collect_diff(mmfile_t *parent, mmfile_t *target, struct diff_ranges
340340
xecfg.hunk_func = collect_diff_cb;
341341
memset(&ecb, 0, sizeof(ecb));
342342
ecb.priv = &cbdata;
343-
xdi_diff(parent, target, &xpp, &xecfg, &ecb);
343+
return xdi_diff(parent, target, &xpp, &xecfg, &ecb);
344344
}
345345

346346
/*
@@ -1030,7 +1030,8 @@ static int process_diff_filepair(struct rev_info *rev,
10301030
}
10311031

10321032
diff_ranges_init(&diff);
1033-
collect_diff(&file_parent, &file_target, &diff);
1033+
if (collect_diff(&file_parent, &file_target, &diff))
1034+
die("unable to generate diff for %s", pair->one->path);
10341035

10351036
/* NEEDSWORK should apply some heuristics to prevent mismatches */
10361037
free(rg->path);

ll-merge.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
8888
xmparam_t xmp;
8989
assert(opts);
9090

91-
if (buffer_is_binary(orig->ptr, orig->size) ||
91+
if (orig->size > MAX_XDIFF_SIZE ||
92+
src1->size > MAX_XDIFF_SIZE ||
93+
src2->size > MAX_XDIFF_SIZE ||
94+
buffer_is_binary(orig->ptr, orig->size) ||
9295
buffer_is_binary(src1->ptr, src1->size) ||
9396
buffer_is_binary(src2->ptr, src2->size)) {
9497
return ll_binary_merge(drv_unused, result,

t/lib-httpd/apache.conf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ RewriteRule ^/smart-redir-perm/(.*)$ /smart/$1 [R=301]
119119
RewriteRule ^/smart-redir-temp/(.*)$ /smart/$1 [R=302]
120120
RewriteRule ^/smart-redir-auth/(.*)$ /auth/smart/$1 [R=301]
121121
RewriteRule ^/smart-redir-limited/(.*)/info/refs$ /smart/$1/info/refs [R=301]
122+
RewriteRule ^/ftp-redir/(.*)$ ftp://localhost:1000/$1 [R=302]
123+
124+
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]
125+
RewriteRule ^/loop-redir/(.*)$ /loop-redir/x-$1 [R=302]
122126

123127
<IfDefine SSL>
124128
LoadModule ssl_module modules/mod_ssl.so

0 commit comments

Comments
 (0)