Skip to content

Commit 1f6444a

Browse files
jeffhostetlerdscho
authored andcommitted
gvfs-helper: ignore .idx files in prefetch multi-part responses
The GVFS cache server can return multiple pairs of (.pack, .idx) files. If both are provided, `gvfs-helper` assumes that they are valid without any validation. This might cause problems if the .pack file is corrupt inside the data stream. (This might happen if the cache server sends extra unexpected STDERR data or if the .pack file is corrupt on the cache server's disk.) All of the .pack file verification logic is already contained within `git index-pack`, so let's ignore the .idx from the data stream and force compute it. This defeats the purpose of some of the data cacheing on the cache server, but safety is more important. Signed-off-by: Jeff Hostetler <jeffhostetler@github.com>
1 parent 0268d56 commit 1f6444a

File tree

2 files changed

+24
-38
lines changed

2 files changed

+24
-38
lines changed

gvfs-helper.c

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,7 +2134,6 @@ static void extract_packfile_from_multipack(
21342134
{
21352135
struct ph ph;
21362136
struct tempfile *tempfile_pack = NULL;
2137-
struct tempfile *tempfile_idx = NULL;
21382137
int result = -1;
21392138
int b_no_idx_in_multipack;
21402139
struct object_id packfile_checksum;
@@ -2168,16 +2167,14 @@ static void extract_packfile_from_multipack(
21682167
b_no_idx_in_multipack = (ph.idx_len == maximum_unsigned_value_of_type(uint64_t) ||
21692168
ph.idx_len == 0);
21702169

2171-
if (b_no_idx_in_multipack) {
2172-
my_create_tempfile(status, 0, "pack", &tempfile_pack, NULL, NULL);
2173-
if (!tempfile_pack)
2174-
goto done;
2175-
} else {
2176-
/* create a pair of tempfiles with the same basename */
2177-
my_create_tempfile(status, 0, "pack", &tempfile_pack, "idx", &tempfile_idx);
2178-
if (!tempfile_pack || !tempfile_idx)
2179-
goto done;
2180-
}
2170+
/*
2171+
* We are going to harden `gvfs-helper` here and ignore the .idx file
2172+
* if it is provided and always compute it locally so that we get the
2173+
* added verification that `git index-pack` provides.
2174+
*/
2175+
my_create_tempfile(status, 0, "pack", &tempfile_pack, NULL, NULL);
2176+
if (!tempfile_pack)
2177+
goto done;
21812178

21822179
/*
21832180
* Copy the current packfile from the open stream and capture
@@ -2204,38 +2201,31 @@ static void extract_packfile_from_multipack(
22042201

22052202
oid_to_hex_r(hex_checksum, &packfile_checksum);
22062203

2207-
if (b_no_idx_in_multipack) {
2208-
/*
2209-
* The server did not send the corresponding .idx, so
2210-
* we have to compute it ourselves.
2211-
*/
2212-
strbuf_addbuf(&temp_path_idx, &temp_path_pack);
2213-
strbuf_strip_suffix(&temp_path_idx, ".pack");
2214-
strbuf_addstr(&temp_path_idx, ".idx");
2204+
/*
2205+
* Always compute the .idx file from the .pack file.
2206+
*/
2207+
strbuf_addbuf(&temp_path_idx, &temp_path_pack);
2208+
strbuf_strip_suffix(&temp_path_idx, ".pack");
2209+
strbuf_addstr(&temp_path_idx, ".idx");
22152210

2216-
my_run_index_pack(params, status,
2217-
&temp_path_pack, &temp_path_idx,
2218-
NULL);
2219-
if (status->ec != GH__ERROR_CODE__OK)
2220-
goto done;
2211+
my_run_index_pack(params, status,
2212+
&temp_path_pack, &temp_path_idx,
2213+
NULL);
2214+
if (status->ec != GH__ERROR_CODE__OK)
2215+
goto done;
22212216

2222-
} else {
2217+
if (!b_no_idx_in_multipack) {
22232218
/*
22242219
* Server sent the .idx immediately after the .pack in the
2225-
* data stream. I'm tempted to verify it, but that defeats
2226-
* the purpose of having it cached...
2220+
* data stream. Skip over it.
22272221
*/
2228-
if (my_copy_fd_len(fd_multipack, get_tempfile_fd(tempfile_idx),
2229-
ph.idx_len) < 0) {
2222+
if (lseek(fd_multipack, ph.idx_len, SEEK_CUR) < 0) {
22302223
strbuf_addf(&status->error_message,
2231-
"could not extract index[%d] in multipack",
2224+
"could not skip index[%d] in multipack",
22322225
k);
22332226
status->ec = GH__ERROR_CODE__COULD_NOT_INSTALL_PREFETCH;
22342227
goto done;
22352228
}
2236-
2237-
strbuf_addstr(&temp_path_idx, get_tempfile_path(tempfile_idx));
2238-
close_tempfile_gently(tempfile_idx);
22392229
}
22402230

22412231
strbuf_addf(&buf_timestamp, "%u", (unsigned int)ph.timestamp);
@@ -2251,7 +2241,6 @@ static void extract_packfile_from_multipack(
22512241

22522242
done:
22532243
delete_tempfile(&tempfile_pack);
2254-
delete_tempfile(&tempfile_idx);
22552244
strbuf_release(&temp_path_pack);
22562245
strbuf_release(&temp_path_idx);
22572246
strbuf_release(&final_path_pack);

t/t5799-gvfs-helper.sh

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,14 +1404,11 @@ test_expect_success 'prefetch corrupt pack without idx' '
14041404

14051405
# Send corrupt PACK files with IDX files. Since the cache server
14061406
# sends both, `gvfs-helper` might fail to verify both of them.
1407-
test_expect_failure 'prefetch corrupt pack with corrupt idx' '
1407+
test_expect_success 'prefetch corrupt pack with corrupt idx' '
14081408
test_when_finished "per_test_cleanup" &&
14091409
start_gvfs_protocol_server_with_mayhem \
14101410
bad_prefetch_pack_sha &&
14111411
1412-
# TODO This is a false-positive since `gvfs-helper`
1413-
# TODO does not verify either of them when a pair
1414-
# TODO is sent.
14151412
test_must_fail \
14161413
git -C "$REPO_T1" gvfs-helper \
14171414
--cache-server=disable \

0 commit comments

Comments
 (0)