commit 9394843506b5859aab24498152a3adcf21a76b12 from: Stefan Sperling via: Thomas Adam date: Mon Jun 13 17:55:22 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 - a0f32f336ed3ba83f8d1afc8165502d06c472866 commit + 9394843506b5859aab24498152a3adcf21a76b12 blob - 0e3f94fa40530b3a7da3a2953d72393dce749ff8 blob + 873467bcc9388aac56c737347130ba38ef7f9564 --- lib/repository.c +++ lib/repository.c @@ -1341,6 +1341,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; @@ -1348,8 +1349,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; }