summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2016-02-22 17:44:42 -0500
committerJunio C Hamano <gitster@pobox.com>2016-02-22 14:51:09 -0800
commite0b837351084c3cb52c5acaf8a505835e631744a (patch)
tree2e1fa5ee6e55031c476e081f25a466f59245a68d
parent20574f551bcc5fcf0f0e20236af174754fa11363 (diff)
downloadgit-e0b837351084c3cb52c5acaf8a505835e631744a.tar.gz
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>
-rw-r--r--dir.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/dir.c b/dir.c
index 9c92be1dbc..3087b7eb2e 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);