Skip to content

Commit

Permalink
gvfs-helper: verify loose objects after write
Browse files Browse the repository at this point in the history
It is possible that a loose object that is written from a GVFS protocol
"get object" request does not match the expected hash. Error out in this
case.

2021-10-30: The prototype for read_loose_object() changed in 31deb28 (fsck:
don't hard die on invalid object types, 2021-10-01) and 96e41f5 (fsck:
report invalid object type-path combinations, 2021-10-01).

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
  • Loading branch information
derrickstolee authored and dscho committed Aug 16, 2023
1 parent 1eb0318 commit d3df430
Showing 1 changed file with 40 additions and 0 deletions.
40 changes: 40 additions & 0 deletions gvfs-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1884,6 +1884,33 @@ static void install_packfile(struct gh__request_params *params,
child_process_clear(&ip);
}

/*
* Wrapper for read_loose_object() to read and verify the hash of a
* loose object, and discard the contents buffer.
*
* Returns 0 on success, negative on error (details may be written to stderr).
*/
static int verify_loose_object(const char *path,
const struct object_id *expected_oid)
{
enum object_type type;
void *contents = NULL;
unsigned long size;
struct strbuf type_name = STRBUF_INIT;
int ret;
struct object_info oi = OBJECT_INFO_INIT;
struct object_id real_oid = *null_oid();
oi.typep = &type;
oi.sizep = &size;
oi.type_name = &type_name;

ret = read_loose_object(path, expected_oid, &real_oid, &contents, &oi);
if (!ret)
free(contents);

return ret;
}

/*
* Convert the tempfile into a permanent loose object in the ODB.
*/
Expand Down Expand Up @@ -1915,6 +1942,19 @@ static void install_loose(struct gh__request_params *params,
strbuf_addstr(&tmp_path, get_tempfile_path(params->tempfile));
close_tempfile_gently(params->tempfile);

/*
* Compute the hash of the received content (while it is still
* in a temp file) and verify that it matches the OID that we
* requested and was not corrupted.
*/
if (verify_loose_object(tmp_path.buf, &params->loose_oid)) {
strbuf_addf(&status->error_message,
"hash failed for received loose object '%s'",
oid_to_hex(&params->loose_oid));
status->ec = GH__ERROR_CODE__COULD_NOT_INSTALL_LOOSE;
goto cleanup;
}

/*
* Try to install the tempfile as the actual loose object.
*
Expand Down

0 comments on commit d3df430

Please sign in to comment.