]> git.ipfire.org Git - thirdparty/git.git/commit - config.c
add core.maxTreeDepth config
authorJeff King <peff@peff.net>
Thu, 31 Aug 2023 06:21:00 +0000 (02:21 -0400)
committerJunio C Hamano <gitster@pobox.com>
Thu, 31 Aug 2023 22:51:07 +0000 (15:51 -0700)
commitbe20128bfa5423503081ba1884e5367c91849d9e
tree96b745b487a2d3d17e550bbcab0ab166edf5c6f4
parent0fbcaef6b49250eb92b08e70f815962c729d5615
add core.maxTreeDepth config

Most of our tree traversal algorithms use recursion to visit sub-trees.
For pathologically large trees, this can cause us to run out of stack
space and abort in an uncontrolled way. Let's put our own limit here so
that we can fail gracefully rather than segfaulting.

In similar cases where we recursed along the commit graph, we rewrote
the algorithms to avoid recursion and keep any stack data on the heap.
But the commit graph is meant to grow without bound, whereas it's not an
imposition to put a limit on the maximum size of tree we'll handle.

And this has a bonus side effect: coupled with a limit on individual
tree entry names, this limits the total size of a path we may encounter.
This gives us an extra protection against code handling long path names
which may suffer from integer overflows in the size (which could then be
exploited by malicious trees).

The default of 4096 is set to be much longer than anybody would care
about in the real world. Even with single-letter interior tree names
(like "a/b/c"), such a path is at least 8191 bytes. While most operating
systems will let you create such a path incrementally, trying to
reference the whole thing in a system call (as Git would do when
actually trying to access it) will result in ENAMETOOLONG. Coupled with
the recent fsck.largePathname warning, the maximum total pathname Git
will handle is (by default) 16MB.

This config option doesn't do anything yet; future patches will convert
various algorithms to respect the limit.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config/core.txt
config.c
environment.c
environment.h