summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2017-05-19 14:06:15 +0200
committerPatrick Steinhardt <ps@pks.im>2017-06-06 09:38:44 +0200
commit064a60e96fc0ac134c9cba7b99bd31e1afbef886 (patch)
tree4561fc8e306ada8d4356e1d4517748675fc1c738
parentc71dff7e8a1bde298972c10901802608bd4cbb55 (diff)
downloadlibgit2-064a60e96fc0ac134c9cba7b99bd31e1afbef886.tar.gz
index: verify we have enough space left when writing index entries
In our code writing index entries, we carry around a `disk_size` representing how much memory we have in total and pass this value to `git_encode_varint` to do bounds checks. This does not make much sense, as at the time when passing on this variable it is already out of date. Fix this by subtracting used memory from `disk_size` as we go along. Furthermore, assert we've actually got enough space left to do the final path memcpy.
-rw-r--r--src/index.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/index.c b/src/index.c
index 860adaf12..c29e90fb0 100644
--- a/src/index.c
+++ b/src/index.c
@@ -2655,15 +2655,34 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
ondisk_ext->flags_extended = htons(entry->flags_extended &
GIT_IDXENTRY_EXTENDED_FLAGS);
path = ondisk_ext->path;
- }
- else
+ disk_size -= offsetof(struct entry_long, path);
+ } else {
path = ondisk->path;
+ disk_size -= offsetof(struct entry_short, path);
+ }
if (last) {
- path += git_encode_varint((unsigned char *) path,
+ varint_len = git_encode_varint((unsigned char *) path,
disk_size, same_len);
+ assert(varint_len > 0);
+ path += varint_len;
+ disk_size -= varint_len;
+
+ /*
+ * If using path compression, we are not allowed
+ * to have additional trailing NULs.
+ */
+ assert(disk_size == path_len + 1);
+ } else {
+ /*
+ * If no path compression is used, we do have
+ * NULs as padding. As such, simply assert that
+ * we have enough space left to write the path.
+ */
+ assert(disk_size > path_len);
}
- memcpy(path, path_start, path_len);
+
+ memcpy(path, path_start, path_len + 1);
return 0;
}