Skip to content

Commit bb3a926

Browse files
pks-tgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e0bfc0b commit bb3a926

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

fsck.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,38 +1170,41 @@ static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata)
11701170
static int fsck_blob(const struct object_id *oid, const char *buf,
11711171
unsigned long size, struct fsck_options *options)
11721172
{
1173-
struct fsck_gitmodules_data data;
1174-
struct config_options config_opts = { 0 };
1175-
1176-
if (!oidset_contains(&options->gitmodules_found, oid))
1177-
return 0;
1178-
oidset_insert(&options->gitmodules_done, oid);
1173+
int ret = 0;
11791174

11801175
if (object_on_skiplist(options, oid))
11811176
return 0;
11821177

1183-
if (!buf) {
1184-
/*
1185-
* A missing buffer here is a sign that the caller found the
1186-
* blob too gigantic to load into memory. Let's just consider
1187-
* that an error.
1188-
*/
1189-
return report(options, oid, OBJ_BLOB,
1190-
FSCK_MSG_GITMODULES_LARGE,
1191-
".gitmodules too large to parse");
1178+
if (oidset_contains(&options->gitmodules_found, oid)) {
1179+
struct config_options config_opts = { 0 };
1180+
struct fsck_gitmodules_data data;
1181+
1182+
oidset_insert(&options->gitmodules_done, oid);
1183+
1184+
if (!buf) {
1185+
/*
1186+
* A missing buffer here is a sign that the caller found the
1187+
* blob too gigantic to load into memory. Let's just consider
1188+
* that an error.
1189+
*/
1190+
return report(options, oid, OBJ_BLOB,
1191+
FSCK_MSG_GITMODULES_LARGE,
1192+
".gitmodules too large to parse");
1193+
}
1194+
1195+
data.oid = oid;
1196+
data.options = options;
1197+
data.ret = 0;
1198+
config_opts.error_action = CONFIG_ERROR_SILENT;
1199+
if (git_config_from_mem(fsck_gitmodules_fn, CONFIG_ORIGIN_BLOB,
1200+
".gitmodules", buf, size, &data, &config_opts))
1201+
data.ret |= report(options, oid, OBJ_BLOB,
1202+
FSCK_MSG_GITMODULES_PARSE,
1203+
"could not parse gitmodules blob");
1204+
ret |= data.ret;
11921205
}
11931206

1194-
data.oid = oid;
1195-
data.options = options;
1196-
data.ret = 0;
1197-
config_opts.error_action = CONFIG_ERROR_SILENT;
1198-
if (git_config_from_mem(fsck_gitmodules_fn, CONFIG_ORIGIN_BLOB,
1199-
".gitmodules", buf, size, &data, &config_opts))
1200-
data.ret |= report(options, oid, OBJ_BLOB,
1201-
FSCK_MSG_GITMODULES_PARSE,
1202-
"could not parse gitmodules blob");
1203-
1204-
return data.ret;
1207+
return ret;
12051208
}
12061209

12071210
int fsck_object(struct object *obj, void *data, unsigned long size,

0 commit comments

Comments
 (0)