dir-iterator: prevent top-level symlinks without FOLLOW_SYMLINKS
When using the dir_iterator API, we first stat(2) the base path, and
then use that as a starting point to enumerate the directory's contents.
If the directory contains symbolic links, we will immediately die() upon
encountering them without the `FOLLOW_SYMLINKS` flag. The same is not
true when resolving the top-level directory, though.
As explained in a previous commit, this oversight in 6f054f9fb3
(builtin/clone.c: disallow `--local` clones with symlinks, 2022-07-28)
can be used as an attack vector to include arbitrary files on a victim's
filesystem from outside of the repository.
Prevent resolving top-level symlinks unless the FOLLOW_SYMLINKS flag is
given, which will cause clones of a repository with a symlink'd
"$GIT_DIR/objects" directory to fail.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
cf8f6ce02a
commit
bffc762f87
@ -203,7 +203,7 @@ struct dir_iterator *dir_iterator_begin(const char *path, unsigned int flags)
|
||||
{
|
||||
struct dir_iterator_int *iter = xcalloc(1, sizeof(*iter));
|
||||
struct dir_iterator *dir_iterator = &iter->base;
|
||||
int saved_errno;
|
||||
int saved_errno, err;
|
||||
|
||||
strbuf_init(&iter->base.path, PATH_MAX);
|
||||
strbuf_addstr(&iter->base.path, path);
|
||||
@ -213,10 +213,15 @@ struct dir_iterator *dir_iterator_begin(const char *path, unsigned int flags)
|
||||
iter->flags = flags;
|
||||
|
||||
/*
|
||||
* Note: stat already checks for NULL or empty strings and
|
||||
* inexistent paths.
|
||||
* Note: stat/lstat already checks for NULL or empty strings and
|
||||
* nonexistent paths.
|
||||
*/
|
||||
if (stat(iter->base.path.buf, &iter->base.st) < 0) {
|
||||
if (iter->flags & DIR_ITERATOR_FOLLOW_SYMLINKS)
|
||||
err = stat(iter->base.path.buf, &iter->base.st);
|
||||
else
|
||||
err = lstat(iter->base.path.buf, &iter->base.st);
|
||||
|
||||
if (err < 0) {
|
||||
saved_errno = errno;
|
||||
goto error_out;
|
||||
}
|
||||
|
Reference in New Issue
Block a user