Skip to content

Commit c793f9c

Browse files
ttaylorrpeff
authored andcommitted
attr.c: move ATTR_MAX_FILE_SIZE check into read_attr_from_buf()
Commit 3c50032 (attr: ignore overly large gitattributes files, 2022-12-01) added a defense-in-depth check to ensure that .gitattributes blobs read from the index do not exceed ATTR_MAX_FILE_SIZE (100 MB). But there were two cases added shortly after 3c50032 was written which do not apply similar protections: - 47cfc9b (attr: add flag `--source` to work with tree-ish, 2023-01-14) - 4723ae1 (attr.c: read attributes in a sparse directory, 2023-08-11) added a similar Ensure that we refuse to process a .gitattributes blob exceeding ATTR_MAX_FILE_SIZE when reading from either an arbitrary tree object or a sparse directory. This is done by pushing the ATTR_MAX_FILE_SIZE check down into the low-level `read_attr_from_buf()`. In doing so, plug a leak in `read_attr_from_index()` where we would accidentally leak the large buffer upon detecting it is too large to process. (Since `read_attr_from_buf()` handles a NULL buffer input, we can remove a NULL check before calling it in `read_attr_from_index()` as well). Co-authored-by: Jeff King <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3c2a3fd commit c793f9c

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

attr.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -765,15 +765,20 @@ static struct attr_stack *read_attr_from_file(const char *path, unsigned flags)
765765
return res;
766766
}
767767

768-
static struct attr_stack *read_attr_from_buf(char *buf, const char *path,
769-
unsigned flags)
768+
static struct attr_stack *read_attr_from_buf(char *buf, size_t length,
769+
const char *path, unsigned flags)
770770
{
771771
struct attr_stack *res;
772772
char *sp;
773773
int lineno = 0;
774774

775775
if (!buf)
776776
return NULL;
777+
if (length >= ATTR_MAX_FILE_SIZE) {
778+
warning(_("ignoring overly large gitattributes blob '%s'"), path);
779+
free(buf);
780+
return NULL;
781+
}
777782

778783
CALLOC_ARRAY(res, 1);
779784
for (sp = buf; *sp;) {
@@ -813,7 +818,7 @@ static struct attr_stack *read_attr_from_blob(struct index_state *istate,
813818
return NULL;
814819
}
815820

816-
return read_attr_from_buf(buf, path, flags);
821+
return read_attr_from_buf(buf, sz, path, flags);
817822
}
818823

819824
static struct attr_stack *read_attr_from_index(struct index_state *istate,
@@ -860,13 +865,7 @@ static struct attr_stack *read_attr_from_index(struct index_state *istate,
860865
stack = read_attr_from_blob(istate, &istate->cache[sparse_dir_pos]->oid, relative_path, flags);
861866
} else {
862867
buf = read_blob_data_from_index(istate, path, &size);
863-
if (!buf)
864-
return NULL;
865-
if (size >= ATTR_MAX_FILE_SIZE) {
866-
warning(_("ignoring overly large gitattributes blob '%s'"), path);
867-
return NULL;
868-
}
869-
stack = read_attr_from_buf(buf, path, flags);
868+
stack = read_attr_from_buf(buf, size, path, flags);
870869
}
871870
return stack;
872871
}

t/t0003-attributes.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,16 @@ test_expect_success EXPENSIVE 'large attributes file ignored in index' '
572572
test_cmp expect err
573573
'
574574

575+
test_expect_success EXPENSIVE 'large attributes blob ignored' '
576+
test_when_finished "git update-index --remove .gitattributes" &&
577+
blob=$(dd if=/dev/zero bs=1048576 count=101 2>/dev/null | git hash-object -w --stdin) &&
578+
git update-index --add --cacheinfo 100644,$blob,.gitattributes &&
579+
tree="$(git write-tree)" &&
580+
git check-attr --cached --all --source="$tree" path >/dev/null 2>err &&
581+
echo "warning: ignoring overly large gitattributes blob ${SQ}.gitattributes${SQ}" >expect &&
582+
test_cmp expect err
583+
'
584+
575585
test_expect_success 'builtin object mode attributes work (dir and regular paths)' '
576586
>normal &&
577587
attr_check_object_mode normal 100644 &&

0 commit comments

Comments
 (0)