fsck: check .gitmodules content
This patch detects and blocks submodule names which do not match the policy set forth in submodule-config. These should already be caught by the submodule code itself, but putting the check here means that newer versions of Git can protect older ones from malicious entries (e.g., a server with receive.fsckObjects will block the objects, protecting clients which fetch from it). As a side effect, this means fsck will also complain about .gitmodules files that cannot be parsed (or were larger than core.bigFileThreshold). Signed-off-by: Jeff King <peff@peff.net>
This commit is contained in:
parent
2738744426
commit
ed8b10f631
58
fsck.c
58
fsck.c
@ -12,6 +12,8 @@
|
||||
#include "decorate.h"
|
||||
#include "oidset.h"
|
||||
#include "packfile.h"
|
||||
#include "submodule-config.h"
|
||||
#include "config.h"
|
||||
|
||||
static struct oidset gitmodules_found = OIDSET_INIT;
|
||||
static struct oidset gitmodules_done = OIDSET_INIT;
|
||||
@ -59,6 +61,8 @@ static struct oidset gitmodules_done = OIDSET_INIT;
|
||||
FUNC(ZERO_PADDED_DATE, ERROR) \
|
||||
FUNC(GITMODULES_MISSING, ERROR) \
|
||||
FUNC(GITMODULES_BLOB, ERROR) \
|
||||
FUNC(GITMODULES_PARSE, ERROR) \
|
||||
FUNC(GITMODULES_NAME, ERROR) \
|
||||
/* warnings */ \
|
||||
FUNC(BAD_FILEMODE, WARN) \
|
||||
FUNC(EMPTY_NAME, WARN) \
|
||||
@ -911,10 +915,64 @@ static int fsck_tag(struct tag *tag, const char *data,
|
||||
return fsck_tag_buffer(tag, data, size, options);
|
||||
}
|
||||
|
||||
struct fsck_gitmodules_data {
|
||||
struct object *obj;
|
||||
struct fsck_options *options;
|
||||
int ret;
|
||||
};
|
||||
|
||||
static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata)
|
||||
{
|
||||
struct fsck_gitmodules_data *data = vdata;
|
||||
const char *subsection, *key;
|
||||
int subsection_len;
|
||||
char *name;
|
||||
|
||||
if (parse_config_key(var, "submodule", &subsection, &subsection_len, &key) < 0 ||
|
||||
!subsection)
|
||||
return 0;
|
||||
|
||||
name = xmemdupz(subsection, subsection_len);
|
||||
if (check_submodule_name(name) < 0)
|
||||
data->ret |= report(data->options, data->obj,
|
||||
FSCK_MSG_GITMODULES_NAME,
|
||||
"disallowed submodule name: %s",
|
||||
name);
|
||||
free(name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsck_blob(struct blob *blob, const char *buf,
|
||||
unsigned long size, struct fsck_options *options)
|
||||
{
|
||||
struct fsck_gitmodules_data data;
|
||||
|
||||
if (!oidset_contains(&gitmodules_found, &blob->object.oid))
|
||||
return 0;
|
||||
oidset_insert(&gitmodules_done, &blob->object.oid);
|
||||
|
||||
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, &blob->object,
|
||||
FSCK_MSG_GITMODULES_PARSE,
|
||||
".gitmodules too large to parse");
|
||||
}
|
||||
|
||||
data.obj = &blob->object;
|
||||
data.options = options;
|
||||
data.ret = 0;
|
||||
if (git_config_from_mem(fsck_gitmodules_fn, CONFIG_ORIGIN_BLOB,
|
||||
".gitmodules", buf, size, &data))
|
||||
data.ret |= report(options, &blob->object,
|
||||
FSCK_MSG_GITMODULES_PARSE,
|
||||
"could not parse gitmodules blob");
|
||||
|
||||
return data.ret;
|
||||
}
|
||||
|
||||
int fsck_object(struct object *obj, void *data, unsigned long size,
|
||||
|
Loading…
Reference in New Issue
Block a user