Skip to content

Commit 45e6315

Browse files
derrickstoleedscho
authored andcommitted
gvfs-helper: verify loose objects after write
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>
1 parent d87f0c7 commit 45e6315

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

Diff for: gvfs-helper.c

+40
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,33 @@ static void install_packfile(struct gh__request_params *params,
18891889
child_process_clear(&ip);
18901890
}
18911891

1892+
/*
1893+
* Wrapper for read_loose_object() to read and verify the hash of a
1894+
* loose object, and discard the contents buffer.
1895+
*
1896+
* Returns 0 on success, negative on error (details may be written to stderr).
1897+
*/
1898+
static int verify_loose_object(const char *path,
1899+
const struct object_id *expected_oid)
1900+
{
1901+
enum object_type type;
1902+
void *contents = NULL;
1903+
unsigned long size;
1904+
struct strbuf type_name = STRBUF_INIT;
1905+
int ret;
1906+
struct object_info oi = OBJECT_INFO_INIT;
1907+
struct object_id real_oid = *null_oid();
1908+
oi.typep = &type;
1909+
oi.sizep = &size;
1910+
oi.type_name = &type_name;
1911+
1912+
ret = read_loose_object(path, expected_oid, &real_oid, &contents, &oi);
1913+
free(contents);
1914+
strbuf_release(&type_name);
1915+
1916+
return ret;
1917+
}
1918+
18921919
/*
18931920
* Convert the tempfile into a permanent loose object in the ODB.
18941921
*/
@@ -1920,6 +1947,19 @@ static void install_loose(struct gh__request_params *params,
19201947
strbuf_addstr(&tmp_path, get_tempfile_path(params->tempfile));
19211948
close_tempfile_gently(params->tempfile);
19221949

1950+
/*
1951+
* Compute the hash of the received content (while it is still
1952+
* in a temp file) and verify that it matches the OID that we
1953+
* requested and was not corrupted.
1954+
*/
1955+
if (verify_loose_object(tmp_path.buf, &params->loose_oid)) {
1956+
strbuf_addf(&status->error_message,
1957+
"hash failed for received loose object '%s'",
1958+
oid_to_hex(&params->loose_oid));
1959+
status->ec = GH__ERROR_CODE__COULD_NOT_INSTALL_LOOSE;
1960+
goto cleanup;
1961+
}
1962+
19231963
/*
19241964
* Try to install the tempfile as the actual loose object.
19251965
*

0 commit comments

Comments
 (0)