* [PATCH] Don't smash stack when $GIT_ALTERNATE_OBJECT_DIRECTORIES is too long
@ 2007-07-03 10:40 Jim Meyering
2007-07-04 5:10 ` Junio C Hamano
0 siblings, 1 reply; 2+ messages in thread
From: Jim Meyering @ 2007-07-03 10:40 UTC (permalink / raw)
To: git
There is no restriction on the length of the name returned by
get_object_directory, other than the fact that it must be a stat'able
git object directory. That means its name may have length up to
PATH_MAX-1 (i.e., often 4095) not counting the trailing NUL.
Combine that with the assumption that the concatenation of that name and
suffixes like "/info/alternates" and "/pack/---long-name---.idx" will fit
in a buffer of length PATH_MAX, and you see the problem. Here's a fix:
sha1_file.c (prepare_packed_git_one): Lengthen "path" buffer
so we are guaranteed to be able to append "/pack/" without checking.
Skip any directory entry that is too long to be appended.
(read_info_alternates): Protect against a similar buffer overrun.
Before this change, using the following admittedly contrived environment
setting would cause many git commands to clobber their stack and segfault
on a system with PATH_MAX == 4096:
t=$(perl -e '$s=".git/objects";$n=(4096-6-length($s))/2;print "./"x$n . $s')
export GIT_ALTERNATE_OBJECT_DIRECTORIES=$t
touch g
./git-update-index --add g
If you run the above commands, you'll soon notice that many
git commands now segfault, so you'll want to do this:
unset GIT_ALTERNATE_OBJECT_DIRECTORIES
Signed-off-by: Jim Meyering <jim@meyering.net>
---
sha1_file.c | 16 +++++++++++++---
1 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index f2b1ae0..1efd9ae 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -352,10 +352,14 @@ static void read_info_alternates(const char * relative_base, int depth)
char *map;
size_t mapsz;
struct stat st;
- char path[PATH_MAX];
+ const char alt_file_name[] = "info/alternates";
+ /* Given that relative_base is no longer than PATH_MAX,
+ ensure that "path" has enough space to append "/", the
+ file name, "info/alternates", and a trailing NUL. */
+ char path[PATH_MAX + 1 + sizeof alt_file_name];
int fd;
- sprintf(path, "%s/info/alternates", relative_base);
+ sprintf(path, "%s/%s", relative_base, alt_file_name);
fd = open(path, O_RDONLY);
if (fd < 0)
return;
@@ -836,7 +840,10 @@ void install_packed_git(struct packed_git *pack)
static void prepare_packed_git_one(char *objdir, int local)
{
- char path[PATH_MAX];
+ /* Ensure that this buffer is large enough so that we can
+ append "/pack/" without clobbering the stack even if
+ strlen(objdir) were PATH_MAX. */
+ char path[PATH_MAX + 1 + 4 + 1 + 1];
int len;
DIR *dir;
struct dirent *de;
@@ -858,6 +865,9 @@ static void prepare_packed_git_one(char *objdir, int local)
if (!has_extension(de->d_name, ".idx"))
continue;
+ if (len + namelen + 1 > sizeof(path))
+ continue;
+
/* Don't reopen a pack we already have. */
strcpy(path + len, de->d_name);
for (p = packed_git; p; p = p->next) {
--
1.5.2.2.646.g71e55-dirty
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] Don't smash stack when $GIT_ALTERNATE_OBJECT_DIRECTORIES is too long
2007-07-03 10:40 [PATCH] Don't smash stack when $GIT_ALTERNATE_OBJECT_DIRECTORIES is too long Jim Meyering
@ 2007-07-04 5:10 ` Junio C Hamano
0 siblings, 0 replies; 2+ messages in thread
From: Junio C Hamano @ 2007-07-04 5:10 UTC (permalink / raw)
To: Jim Meyering; +Cc: git
Thanks.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-07-04 5:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-03 10:40 [PATCH] Don't smash stack when $GIT_ALTERNATE_OBJECT_DIRECTORIES is too long Jim Meyering
2007-07-04 5:10 ` Junio C Hamano
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.