commit 6a881297759a4b3c4f62093aef5fdbaad0dae8df from: Stefan Sperling date: Thu Jun 02 12:32:00 2022 UTC properly swap cached struct pack array elements in got_repo_cache_pack() Avoids clobbering open files for delta base/accumulation, leaking file descriptors, and triggering errors from close(2) during got_repo_close() as we try to close the same file descriptor more than once. commit - b72706c3d172544098fcd24fd639374694a8fce9 commit + 6a881297759a4b3c4f62093aef5fdbaad0dae8df blob - 66dce96b54785bf451b150d44880b57fab657b42 blob + 5be66db732b6a51d032ae835a233ef3cbcd3733b --- lib/repository.c +++ lib/repository.c @@ -1346,6 +1346,7 @@ got_repo_cache_pack(struct got_pack **packp, struct go } if (i == repo->pack_cache_size) { + struct got_pack tmp; err = got_pack_close(&repo->packs[i - 1]); if (err) return err; @@ -1353,8 +1354,10 @@ got_repo_cache_pack(struct got_pack **packp, struct go return got_error_from_errno("ftruncate"); if (ftruncate(repo->packs[i - 1].accumfd, 0L) == -1) return got_error_from_errno("ftruncate"); - memmove(&repo->packs[1], &repo->packs[0], - sizeof(repo->packs) - sizeof(repo->packs[0])); + memcpy(&tmp, &repo->packs[i - 1], sizeof(tmp)); + memcpy(&repo->packs[i - 1], &repo->packs[0], + sizeof(repo->packs[i - 1])); + memcpy(&repo->packs[0], &tmp, sizeof(repo->packs[0])); i = 0; }