зеркало из https://github.com/microsoft/git.git
Merge branch 'cc/receive-pack-limit'
An incoming "git push" that attempts to push too many bytes can now be rejected by setting a new configuration variable at the receiving end. * cc/receive-pack-limit: receive-pack: allow a maximum input size to be specified unpack-objects: add --max-input-size=<size> option index-pack: add --max-input-size=<size> option
This commit is contained in:
Коммит
da3b6f06e1
|
@ -2517,6 +2517,12 @@ receive.unpackLimit::
|
|||
especially on slow filesystems. If not set, the value of
|
||||
`transfer.unpackLimit` is used instead.
|
||||
|
||||
receive.maxInputSize::
|
||||
If the size of the incoming pack stream is larger than this
|
||||
limit, then git-receive-pack will error out, instead of
|
||||
accepting the pack file. If not set or set to 0, then the size
|
||||
is unlimited.
|
||||
|
||||
receive.denyDeletes::
|
||||
If set to true, git-receive-pack will deny a ref update that deletes
|
||||
the ref. Use this to prevent such a ref deletion via a push.
|
||||
|
|
|
@ -87,6 +87,8 @@ OPTIONS
|
|||
Specifying 0 will cause Git to auto-detect the number of CPU's
|
||||
and use maximum 3 threads.
|
||||
|
||||
--max-input-size=<size>::
|
||||
Die, if the pack is larger than <size>.
|
||||
|
||||
Note
|
||||
----
|
||||
|
|
|
@ -33,6 +33,9 @@ post-update hooks found in the Documentation/howto directory.
|
|||
option, which tells it if updates to a ref should be denied if they
|
||||
are not fast-forwards.
|
||||
|
||||
A number of other receive.* config options are available to tweak
|
||||
its behavior, see linkgit:git-config[1].
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
<directory>::
|
||||
|
|
|
@ -44,6 +44,9 @@ OPTIONS
|
|||
--strict::
|
||||
Don't write objects with broken content or links.
|
||||
|
||||
--max-input-size=<size>::
|
||||
Die, if the pack is larger than <size>.
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
||||
|
|
|
@ -87,6 +87,7 @@ static struct progress *progress;
|
|||
static unsigned char input_buffer[4096];
|
||||
static unsigned int input_offset, input_len;
|
||||
static off_t consumed_bytes;
|
||||
static off_t max_input_size;
|
||||
static unsigned deepest_delta;
|
||||
static git_SHA_CTX input_ctx;
|
||||
static uint32_t input_crc32;
|
||||
|
@ -297,6 +298,8 @@ static void use(int bytes)
|
|||
if (signed_add_overflows(consumed_bytes, bytes))
|
||||
die(_("pack too large for current definition of off_t"));
|
||||
consumed_bytes += bytes;
|
||||
if (max_input_size && consumed_bytes > max_input_size)
|
||||
die(_("pack exceeds maximum allowed size"));
|
||||
}
|
||||
|
||||
static const char *open_pack_file(const char *pack_name)
|
||||
|
@ -1714,6 +1717,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
|
|||
opts.off32_limit = strtoul(c+1, &c, 0);
|
||||
if (*c || opts.off32_limit & 0x80000000)
|
||||
die(_("bad %s"), arg);
|
||||
} else if (skip_prefix(arg, "--max-input-size=", &arg)) {
|
||||
max_input_size = strtoumax(arg, NULL, 10);
|
||||
} else
|
||||
usage(index_pack_usage);
|
||||
continue;
|
||||
|
|
|
@ -46,6 +46,7 @@ static int transfer_unpack_limit = -1;
|
|||
static int advertise_atomic_push = 1;
|
||||
static int advertise_push_options;
|
||||
static int unpack_limit = 100;
|
||||
static off_t max_input_size;
|
||||
static int report_status;
|
||||
static int use_sideband;
|
||||
static int use_atomic;
|
||||
|
@ -212,6 +213,11 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(var, "receive.maxinputsize") == 0) {
|
||||
max_input_size = git_config_int64(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git_default_config(var, value, cb);
|
||||
}
|
||||
|
||||
|
@ -1648,6 +1654,9 @@ static const char *unpack(int err_fd, struct shallow_info *si)
|
|||
if (fsck_objects)
|
||||
argv_array_pushf(&child.args, "--strict%s",
|
||||
fsck_msg_types.buf);
|
||||
if (max_input_size)
|
||||
argv_array_pushf(&child.args, "--max-input-size=%"PRIuMAX,
|
||||
(uintmax_t)max_input_size);
|
||||
child.no_stdout = 1;
|
||||
child.err = err_fd;
|
||||
child.git_cmd = 1;
|
||||
|
@ -1676,6 +1685,9 @@ static const char *unpack(int err_fd, struct shallow_info *si)
|
|||
fsck_msg_types.buf);
|
||||
if (!reject_thin)
|
||||
argv_array_push(&child.args, "--fix-thin");
|
||||
if (max_input_size)
|
||||
argv_array_pushf(&child.args, "--max-input-size=%"PRIuMAX,
|
||||
(uintmax_t)max_input_size);
|
||||
child.out = -1;
|
||||
child.err = err_fd;
|
||||
child.git_cmd = 1;
|
||||
|
|
|
@ -19,6 +19,7 @@ static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict]
|
|||
static unsigned char buffer[4096];
|
||||
static unsigned int offset, len;
|
||||
static off_t consumed_bytes;
|
||||
static off_t max_input_size;
|
||||
static git_SHA_CTX ctx;
|
||||
static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
|
||||
|
||||
|
@ -87,6 +88,8 @@ static void use(int bytes)
|
|||
if (signed_add_overflows(consumed_bytes, bytes))
|
||||
die("pack too large for current definition of off_t");
|
||||
consumed_bytes += bytes;
|
||||
if (max_input_size && consumed_bytes > max_input_size)
|
||||
die(_("pack exceeds maximum allowed size"));
|
||||
}
|
||||
|
||||
static void *get_data(unsigned long size)
|
||||
|
@ -550,6 +553,10 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
|
|||
len = sizeof(*hdr);
|
||||
continue;
|
||||
}
|
||||
if (skip_prefix(arg, "--max-input-size=", &arg)) {
|
||||
max_input_size = strtoumax(arg, NULL, 10);
|
||||
continue;
|
||||
}
|
||||
usage(unpack_usage);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
#!/bin/sh
|
||||
|
||||
test_description='check receive input limits'
|
||||
. ./test-lib.sh
|
||||
|
||||
# Let's run tests with different unpack limits: 1 and 10000
|
||||
# When the limit is 1, `git receive-pack` will call `git index-pack`.
|
||||
# When the limit is 10000, `git receive-pack` will call `git unpack-objects`.
|
||||
|
||||
test_pack_input_limit () {
|
||||
case "$1" in
|
||||
index) unpack_limit=1 ;;
|
||||
unpack) unpack_limit=10000 ;;
|
||||
esac
|
||||
|
||||
test_expect_success 'prepare destination repository' '
|
||||
rm -fr dest &&
|
||||
git --bare init dest
|
||||
'
|
||||
|
||||
test_expect_success "set unpacklimit to $unpack_limit" '
|
||||
git --git-dir=dest config receive.unpacklimit "$unpack_limit"
|
||||
'
|
||||
|
||||
test_expect_success 'setting receive.maxInputSize to 512 rejects push' '
|
||||
git --git-dir=dest config receive.maxInputSize 512 &&
|
||||
test_must_fail git push dest HEAD
|
||||
'
|
||||
|
||||
test_expect_success 'bumping limit to 4k allows push' '
|
||||
git --git-dir=dest config receive.maxInputSize 4k &&
|
||||
git push dest HEAD
|
||||
'
|
||||
|
||||
test_expect_success 'prepare destination repository (again)' '
|
||||
rm -fr dest &&
|
||||
git --bare init dest
|
||||
'
|
||||
|
||||
test_expect_success 'lifting the limit allows push' '
|
||||
git --git-dir=dest config receive.maxInputSize 0 &&
|
||||
git push dest HEAD
|
||||
'
|
||||
}
|
||||
|
||||
test_expect_success "create known-size (1024 bytes) commit" '
|
||||
test-genrandom foo 1024 >one-k &&
|
||||
git add one-k &&
|
||||
test_commit one-k
|
||||
'
|
||||
|
||||
test_pack_input_limit index
|
||||
test_pack_input_limit unpack
|
||||
|
||||
test_done
|
Загрузка…
Ссылка в новой задаче