summaryrefslogtreecommitdiff
path: root/dir.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2016-02-22 22:44:42 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-02-22 22:51:09 (GMT)
commite0b837351084c3cb52c5acaf8a505835e631744a (patch)
tree2e1fa5ee6e55031c476e081f25a466f59245a68d /dir.c
parent20574f551bcc5fcf0f0e20236af174754fa11363 (diff)
downloadgit-e0b837351084c3cb52c5acaf8a505835e631744a.zip
git-e0b837351084c3cb52c5acaf8a505835e631744a.tar.gz
git-e0b837351084c3cb52c5acaf8a505835e631744a.tar.bz2
write_untracked_extension: use FLEX_ALLOC helper
We perform unchecked additions when computing the size of a "struct ondisk_untracked_cache". This is unlikely to have an integer overflow in practice, but we'd like to avoid this dangerous pattern to make further audits easier. Note that there's one subtlety here, though. We protect ourselves against a NULL exclude_per_dir entry in our source, and avoid calling strlen() on it, keeping "len" at 0. But later, we unconditionally memcpy "len + 1" bytes to get the trailing NUL byte. If we did have a NULL exclude_per_dir, we would read from bogus memory. As it turns out, though, we always create this field pointing to a string literal, so there's no bug. We can just get rid of the pointless extra conditional. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'dir.c')
-rw-r--r--dir.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/dir.c b/dir.c
index 9c92be1..3087b7e 100644
--- a/dir.c
+++ b/dir.c
@@ -2324,16 +2324,15 @@ void write_untracked_extension(struct strbuf *out, struct untracked_cache *untra
struct ondisk_untracked_cache *ouc;
struct write_data wd;
unsigned char varbuf[16];
- int len = 0, varint_len;
- if (untracked->exclude_per_dir)
- len = strlen(untracked->exclude_per_dir);
- ouc = xmalloc(sizeof(*ouc) + len + 1);
+ int varint_len;
+ size_t len = strlen(untracked->exclude_per_dir);
+
+ FLEX_ALLOC_MEM(ouc, exclude_per_dir, untracked->exclude_per_dir, len);
stat_data_to_disk(&ouc->info_exclude_stat, &untracked->ss_info_exclude.stat);
stat_data_to_disk(&ouc->excludes_file_stat, &untracked->ss_excludes_file.stat);
hashcpy(ouc->info_exclude_sha1, untracked->ss_info_exclude.sha1);
hashcpy(ouc->excludes_file_sha1, untracked->ss_excludes_file.sha1);
ouc->dir_flags = htonl(untracked->dir_flags);
- memcpy(ouc->exclude_per_dir, untracked->exclude_per_dir, len + 1);
varint_len = encode_varint(untracked->ident.len, varbuf);
strbuf_add(out, varbuf, varint_len);