From: Johan Herland <johan@herland.net>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>
Subject: [PATCH 2/2] receive-pack: Add receive.denyObjectLimit to refuse push with too many objects
Date: Fri, 13 May 2011 18:54:31 +0200 [thread overview]
Message-ID: <201105131854.31540.johan@herland.net> (raw)
The new receive.denyObjectLimit config variable defines an upper limit on the
number of objects to accept in a single push. If the number of objects in a
push exceeds this limit, the entire push is immediately aborted without
storing the pushed objects on the server at all.
This is meant to prevent an unintended large push (typically a result of the
user not being aware of exactly what is being pushed, e.g. pushing a large
rewritten history) from entering the repo.
Usually, this kind of limit could be imposed by a pre-receive or update hook,
but both of those run _after_ the pack has been received and stored by
receive-pack, so they cannot prevent the pack from being transferred in the
first place.
Documentation and tests are included.
Signed-off-by: Johan Herland <johan@herland.net>
---
There's something weird going on here: The included test case works as
intended, but when I try to test this in "real-world" conditions,
I don't get the expected error message in the output:
# From inside my git.git repo:
$ git init --bare foo.git
$ (cd foo.git && git config receive.denyObjectLimit 100000)
$ git push foo.git/ master
Pushing to foo.git/
Counting objects: 112383, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (27658/27658), done.
error: pack-objects died of signal 13
error: failed to push some refs to 'foo.git/'
$
So the pack-objects on the local side dies of a broken pipe (as
expected), but the error message from the remote side:
error: unpack failed: received pack exceeds configured receive.denyObjectLimit
is never printed, so the user gets no clue as to why the push failed.
This should be fixed before this patch can be considered for inclusion.
...Johan
Documentation/config.txt | 9 +++++++++
builtin/receive-pack.c | 10 +++++++++-
t/t5400-send-pack.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 62 insertions(+), 1 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 285c7f7..7c60146 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1591,6 +1591,15 @@ receive.unpackLimit::
especially on slow filesystems. If not set, the value of
`transfer.unpackLimit` is used instead.
+receive.denyObjectLimit::
+ If the number of objects received in a push exceeds this limit,
+ then the entire push will be refused. This is meant to prevent
+ an unintended large push (typically a result of the user not
+ being aware of exactly what is being pushed, e.g. pushing a
+ large rewritten history) from entering the repo. If not set,
+ there is no upper limit on the number of objects transferred
+ in a single push.
+
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.
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index e1ba4dc..856650f 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -25,6 +25,7 @@ static int deny_non_fast_forwards;
static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
static int receive_fsck_objects;
+static int receive_deny_limit;
static int receive_unpack_limit = -1;
static int transfer_unpack_limit = -1;
static int unpack_limit = 100;
@@ -63,6 +64,11 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
return 0;
}
+ if (strcmp(var, "receive.denyobjectlimit") == 0) {
+ receive_deny_limit = git_config_int(var, value);
+ return 0;
+ }
+
if (strcmp(var, "receive.unpacklimit") == 0) {
receive_unpack_limit = git_config_int(var, value);
return 0;
@@ -648,7 +654,9 @@ static const char *unpack(void)
"--pack_header=%"PRIu32",%"PRIu32,
ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
- if (ntohl(hdr.hdr_entries) < unpack_limit) {
+ if (receive_deny_limit > 0 && ntohl(hdr.hdr_entries) > receive_deny_limit)
+ return "received pack exceeds configured receive.denyObjectLimit";
+ else if (ntohl(hdr.hdr_entries) < unpack_limit) {
int code, i = 0;
const char *unpacker[4];
unpacker[i++] = "unpack-objects";
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 0eace37..2fbe34b 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -222,4 +222,48 @@ test_expect_success 'deny pushing to delete current branch' '
)
'
+test_expect_success 'deny pushing when receive.denyObjectLimit is exceeded' '
+ rewound_push_setup &&
+ (
+ cd parent &&
+ git config receive.denyObjectLimit 1
+ ) &&
+ (
+ cd child &&
+ git reset --hard origin/master &&
+ echo three > file && git commit -a -m three &&
+ test_must_fail git send-pack ../parent master 2>errs &&
+ grep -q "receive\\.denyObjectLimit" errs
+ ) &&
+ parent_head=$(cd parent && git rev-parse --verify master) &&
+ child_head=$(cd child && git rev-parse --verify master) &&
+ test "$parent_head" != "$child_head"
+'
+
+test_expect_success 'repeated push failure proves that objects were not stored remotely' '
+ (
+ cd child &&
+ test_must_fail git send-pack ../parent master 2>errs &&
+ grep -q "receive\\.denyObjectLimit" errs
+ ) &&
+ parent_head=$(cd parent && git rev-parse --verify master) &&
+ child_head=$(cd child && git rev-parse --verify master) &&
+ test "$parent_head" != "$child_head"
+'
+
+test_expect_success 'increasing receive.denyObjectLimit allows the push' '
+ (
+ cd parent &&
+ git config receive.denyObjectLimit 10
+ ) &&
+ (
+ cd child &&
+ git send-pack ../parent master 2>errs &&
+ test_must_fail grep -q "receive\\.denyObjectLimit" errs
+ ) &&
+ parent_head=$(cd parent && git rev-parse --verify master) &&
+ child_head=$(cd child && git rev-parse --verify master) &&
+ test "$parent_head" = "$child_head"
+'
+
test_done
--
1.7.5.1.354.g761178
--
Johan Herland, <johan@herland.net>
www.herland.net
next reply other threads:[~2011-05-13 16:54 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-13 16:54 Johan Herland [this message]
2011-05-13 17:09 ` [PATCH 2/2] receive-pack: Add receive.denyObjectLimit to refuse push with too many objects Junio C Hamano
2011-05-14 1:43 ` Johan Herland
2011-05-14 2:03 ` [PATCHv2 2/2] receive-pack: Add receive.objectCountLimit " Johan Herland
2011-05-14 2:30 ` Shawn Pearce
2011-05-14 13:17 ` Johan Herland
2011-05-14 22:17 ` Shawn Pearce
2011-05-15 17:42 ` Johan Herland
2011-05-15 21:37 ` [PATCHv3 0/9] Push limits Johan Herland
2011-05-15 21:37 ` [PATCHv3 1/9] Update technical docs to reflect side-band-64k capability in receive-pack Johan Herland
2011-05-15 21:37 ` [PATCHv3 2/9] send-pack: Attempt to retrieve remote status even if pack-objects fails Johan Herland
2011-05-16 4:07 ` Jeff King
2011-05-16 6:13 ` Jeff King
2011-05-16 6:39 ` Jeff King
2011-05-16 6:46 ` [PATCH 1/3] connect: treat generic proxy processes like ssh processes Jeff King
2011-05-16 19:57 ` Johannes Sixt
2011-05-16 23:12 ` Junio C Hamano
2011-05-17 5:54 ` Jeff King
2011-05-17 20:14 ` Johannes Sixt
2011-05-18 8:57 ` Jeff King
2011-05-16 6:52 ` [PATCH 2/3] connect: let callers know if connection is a socket Jeff King
2011-05-16 6:52 ` [PATCH 3/3] send-pack: avoid deadlock on git:// push with failed pack-objects Jeff King
2011-05-16 20:02 ` Johannes Sixt
2011-05-17 5:56 ` Jeff King
2011-05-18 20:24 ` [PATCH] Windows: add a wrapper for the shutdown() system call Johannes Sixt
2011-05-15 21:37 ` [PATCHv3 3/9] pack-objects: Allow --max-pack-size to be used together with --stdout Johan Herland
2011-05-15 22:06 ` Shawn Pearce
2011-05-16 1:39 ` Johan Herland
2011-05-16 6:12 ` Junio C Hamano
2011-05-16 9:27 ` Johan Herland
2011-05-15 21:37 ` [PATCHv3 4/9] pack-objects: Teach new option --max-object-count, similar to --max-pack-size Johan Herland
2011-05-15 22:07 ` Shawn Pearce
2011-05-15 22:31 ` Johan Herland
2011-05-15 23:48 ` Shawn Pearce
2011-05-16 6:25 ` Junio C Hamano
2011-05-16 9:49 ` Johan Herland
2011-05-15 21:37 ` [PATCHv3 5/9] pack-objects: Teach new option --max-commit-count, limiting #commits in pack Johan Herland
2011-05-15 21:37 ` [PATCHv3 6/9] receive-pack: Prepare for addition of the new 'limit-*' family of capabilities Johan Herland
2011-05-16 6:50 ` Junio C Hamano
2011-05-16 9:53 ` Johan Herland
2011-05-16 22:02 ` Sverre Rabbelier
2011-05-16 22:07 ` Junio C Hamano
2011-05-16 22:09 ` Sverre Rabbelier
2011-05-16 22:12 ` Junio C Hamano
2011-05-16 22:16 ` Sverre Rabbelier
2011-05-15 21:37 ` [PATCHv3 7/9] send-pack/receive-pack: Allow server to refuse pushes with too many objects Johan Herland
2011-05-15 21:37 ` [PATCHv3 8/9] send-pack/receive-pack: Allow server to refuse pushing too large packs Johan Herland
2011-05-15 21:37 ` [PATCHv3 9/9] send-pack/receive-pack: Allow server to refuse pushes with too many commits Johan Herland
2011-05-15 21:52 ` [PATCHv3 0/9] Push limits Ævar Arnfjörð Bjarmason
2011-05-14 17:50 ` [PATCHv2 2/2] receive-pack: Add receive.objectCountLimit to refuse push with too many objects Junio C Hamano
2011-05-14 22:27 ` Shawn Pearce
2011-05-13 18:20 ` [PATCH 2/2] receive-pack: Add receive.denyObjectLimit " Johannes Sixt
2011-05-14 1:49 ` Johan Herland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201105131854.31540.johan@herland.net \
--to=johan@herland.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).