Skip to content

Commit 473561f

Browse files
ahuntgitster
authored andcommitted
transport: also free remote_refs in transport_disconnect()
transport_get_remote_refs() can populate the transport struct's remote_refs. transport_disconnect() is already responsible for most of transport's cleanup - therefore we also take care of freeing remote_refs there. There are 2 locations where transport_disconnect() is called before we're done using the returned remote_refs. This patch changes those callsites to only call transport_disconnect() after the returned refs are no longer being used - which is necessary to safely be able to free remote_refs during transport_disconnect(). This commit fixes the following leak which was found while running t0000, but is expected to also fix the same pattern of leak in all locations that use transport_get_remote_refs(): Direct leak of 165 byte(s) in 1 object(s) allocated from: #0 0x49a6b2 in calloc /home/abuild/rpmbuild/BUILD/llvm-11.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:154:3 #1 0x9a72f2 in xcalloc /home/ahunt/oss-fuzz/git/wrapper.c:140:8 #2 0x8ce203 in alloc_ref_with_prefix /home/ahunt/oss-fuzz/git/remote.c:867:20 #3 0x8ce1a2 in alloc_ref /home/ahunt/oss-fuzz/git/remote.c:875:9 #4 0x72f63e in process_ref_v2 /home/ahunt/oss-fuzz/git/connect.c:426:8 #5 0x72f21a in get_remote_refs /home/ahunt/oss-fuzz/git/connect.c:525:8 #6 0x979ab7 in handshake /home/ahunt/oss-fuzz/git/transport.c:305:4 #7 0x97872d in get_refs_via_connect /home/ahunt/oss-fuzz/git/transport.c:339:9 #8 0x9774b5 in transport_get_remote_refs /home/ahunt/oss-fuzz/git/transport.c:1388:4 #9 0x51cf80 in cmd_clone /home/ahunt/oss-fuzz/git/builtin/clone.c:1271:9 #10 0x4cd60d in run_builtin /home/ahunt/oss-fuzz/git/git.c:453:11 #11 0x4cb2da in handle_builtin /home/ahunt/oss-fuzz/git/git.c:704:3 #12 0x4ccc37 in run_argv /home/ahunt/oss-fuzz/git/git.c:771:4 #13 0x4cac29 in cmd_main /home/ahunt/oss-fuzz/git/git.c:902:19 #14 0x69c45e in main /home/ahunt/oss-fuzz/git/common-main.c:52:11 #15 0x7f6a459d5349 in __libc_start_main (/lib64/libc.so.6+0x24349) Signed-off-by: Andrzej Hunt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent de8ecdd commit 473561f

File tree

3 files changed

+8
-6
lines changed

3 files changed

+8
-6
lines changed

builtin/ls-remote.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,6 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
124124
int hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
125125
repo_set_hash_algo(the_repository, hash_algo);
126126
}
127-
if (transport_disconnect(transport))
128-
return 1;
129127

130128
if (!dest && !quiet)
131129
fprintf(stderr, "From %s\n", *remote->url);
@@ -151,5 +149,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
151149
}
152150

153151
ref_array_clear(&ref_array);
152+
if (transport_disconnect(transport))
153+
return 1;
154154
return status;
155155
}

builtin/remote.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -938,20 +938,19 @@ static int get_remote_ref_states(const char *name,
938938
struct ref_states *states,
939939
int query)
940940
{
941-
struct transport *transport;
942-
const struct ref *remote_refs;
943-
944941
states->remote = remote_get(name);
945942
if (!states->remote)
946943
return error(_("No such remote: '%s'"), name);
947944

948945
read_branches();
949946

950947
if (query) {
948+
struct transport *transport;
949+
const struct ref *remote_refs;
950+
951951
transport = transport_get(states->remote, states->remote->url_nr > 0 ?
952952
states->remote->url[0] : NULL);
953953
remote_refs = transport_get_remote_refs(transport, NULL);
954-
transport_disconnect(transport);
955954

956955
states->queried = 1;
957956
if (query & GET_REF_STATES)
@@ -960,6 +959,7 @@ static int get_remote_ref_states(const char *name,
960959
get_head_names(remote_refs, states);
961960
if (query & GET_PUSH_REF_STATES)
962961
get_push_ref_states(remote_refs, states);
962+
transport_disconnect(transport);
963963
} else {
964964
for_each_ref(append_ref_to_tracked_list, states);
965965
string_list_sort(&states->tracked);

transport.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,8 @@ int transport_disconnect(struct transport *transport)
14521452
int ret = 0;
14531453
if (transport->vtable->disconnect)
14541454
ret = transport->vtable->disconnect(transport);
1455+
if (transport->got_remote_refs)
1456+
free_refs((void *)transport->remote_refs);
14551457
free(transport);
14561458
return ret;
14571459
}

0 commit comments

Comments
 (0)