commit 3bfa5a0662f43509affe2e9d123e2bb5742f1cc6 from: Florian Obser via: Thomas Adam date: Thu Jul 21 08:32:00 2022 UTC Prevent use-after-free of packed_refs_path in error path. Found by llvm's scan-build. OK stsp commit - f2c54bde7775ee68219a71b9de403db863b58bbf commit + 3bfa5a0662f43509affe2e9d123e2bb5742f1cc6 blob - 15007ad091c5bbeac874d3a7f095826bb21f3867 blob + 2e6723491391ba8acccf1a7f0ef9085db6cba827 --- lib/reference.c +++ lib/reference.c @@ -453,7 +453,7 @@ got_ref_open(struct got_reference **ref, struct got_re const char *refname, int lock) { const struct got_error *err = NULL; - char *path_refs = NULL; + char *packed_refs_path = NULL, *path_refs = NULL; const char *subdirs[] = { GOT_REF_HEADS, GOT_REF_TAGS, GOT_REF_REMOTES }; @@ -472,7 +472,6 @@ got_ref_open(struct got_reference **ref, struct got_re if (well_known) { err = open_ref(ref, path_refs, "", refname, lock); } else { - char *packed_refs_path; FILE *f; /* Search on-disk refs before packed refs! */ @@ -496,7 +495,6 @@ got_ref_open(struct got_reference **ref, struct got_re goto done; } f = fopen(packed_refs_path, "rbe"); - free(packed_refs_path); if (f != NULL) { struct stat sb; if (fstat(fileno(f), &sb) == -1) { @@ -521,6 +519,7 @@ done: err = got_error_not_ref(refname); if (err && lf) got_lockfile_unlock(lf, -1); + free(packed_refs_path); free(path_refs); return err; } @@ -997,7 +996,7 @@ got_ref_list(struct got_reflist_head *refs, struct got const char *ref_namespace, got_ref_cmp_cb cmp_cb, void *cmp_arg) { const struct got_error *err; - char *packed_refs_path, *path_refs = NULL; + char *packed_refs_path = NULL, *path_refs = NULL; char *abs_namespace = NULL, *buf = NULL; const char *ondisk_ref_namespace = NULL; char *line = NULL; @@ -1090,7 +1089,6 @@ got_ref_list(struct got_reflist_head *refs, struct got } f = fopen(packed_refs_path, "re"); - free(packed_refs_path); if (f) { size_t linesize = 0; ssize_t linelen; @@ -1135,6 +1133,7 @@ got_ref_list(struct got_reflist_head *refs, struct got } } done: + free(packed_refs_path); free(abs_namespace); free(buf); free(line);