summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2022-12-01 15:45:57 +0100
committerJunio C Hamano <gitster@pobox.com>2022-12-09 17:05:00 +0900
commitbb3a9265e505e9593faa260860f9b8929af0963e (patch)
tree7dda05e84e8c8bf639ff989e5bcabc2307052144
parente0bfc0b3b91052a5807b66aea866648087b30b80 (diff)
downloadgit-bb3a9265e505e9593faa260860f9b8929af0963e.tar.xz
fsck: refactor `fsck_blob()` to allow for more checks
In general, we don't need to validate blob contents as they are opaque blobs about whose content Git doesn't need to care about. There are some exceptions though when blobs are linked into trees so that they would be interpreted by Git. We only have a single such check right now though, which is the one for gitmodules that has been added in the context of CVE-2018-11235. Now we have found another vulnerability with gitattributes that can lead to out-of-bounds writes and reads. So let's refactor `fsck_blob()` so that it is more extensible and can check different types of blobs. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--fsck.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/fsck.c b/fsck.c
index 3ec500d707..ddcb2d264c 100644
--- a/fsck.c
+++ b/fsck.c
@@ -1170,38 +1170,41 @@ static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata)
static int fsck_blob(const struct object_id *oid, const char *buf,
unsigned long size, struct fsck_options *options)
{
- struct fsck_gitmodules_data data;
- struct config_options config_opts = { 0 };
-
- if (!oidset_contains(&options->gitmodules_found, oid))
- return 0;
- oidset_insert(&options->gitmodules_done, oid);
+ int ret = 0;
if (object_on_skiplist(options, oid))
return 0;
- if (!buf) {
- /*
- * A missing buffer here is a sign that the caller found the
- * blob too gigantic to load into memory. Let's just consider
- * that an error.
- */
- return report(options, oid, OBJ_BLOB,
- FSCK_MSG_GITMODULES_LARGE,
- ".gitmodules too large to parse");
- }
+ if (oidset_contains(&options->gitmodules_found, oid)) {
+ struct config_options config_opts = { 0 };
+ struct fsck_gitmodules_data data;
- data.oid = oid;
- data.options = options;
- data.ret = 0;
- config_opts.error_action = CONFIG_ERROR_SILENT;
- if (git_config_from_mem(fsck_gitmodules_fn, CONFIG_ORIGIN_BLOB,
- ".gitmodules", buf, size, &data, &config_opts))
- data.ret |= report(options, oid, OBJ_BLOB,
- FSCK_MSG_GITMODULES_PARSE,
- "could not parse gitmodules blob");
+ oidset_insert(&options->gitmodules_done, oid);
- return data.ret;
+ if (!buf) {
+ /*
+ * A missing buffer here is a sign that the caller found the
+ * blob too gigantic to load into memory. Let's just consider
+ * that an error.
+ */
+ return report(options, oid, OBJ_BLOB,
+ FSCK_MSG_GITMODULES_LARGE,
+ ".gitmodules too large to parse");
+ }
+
+ data.oid = oid;
+ data.options = options;
+ data.ret = 0;
+ config_opts.error_action = CONFIG_ERROR_SILENT;
+ if (git_config_from_mem(fsck_gitmodules_fn, CONFIG_ORIGIN_BLOB,
+ ".gitmodules", buf, size, &data, &config_opts))
+ data.ret |= report(options, oid, OBJ_BLOB,
+ FSCK_MSG_GITMODULES_PARSE,
+ "could not parse gitmodules blob");
+ ret |= data.ret;
+ }
+
+ return ret;
}
int fsck_object(struct object *obj, void *data, unsigned long size,