Skip to content

Commit a91ef5b

Browse files
committed
init_db(): fix leak by removing git_init_db_config()
init_db_config_path could be leaked because: 1. git_init_db_config() allocates new data into init_db_config_path on every invocation without freeing preexisting data. 2. git_init_db_config() can be called multiple times for a single git_config() invocation (see docs on git_config() for context). Furthermore, until very recently, git_config(git_init_db_config(), ...) could have been invoked twice in a single process as git_init_db_config() used to be used to handle core.* config settings. This was changed in a previous patch in this series. Freeing the existing value in git_init_db_config() would be the least intrusive fix, however switching to git_config_get_value() simplifies the code further by letting us remove the static pointer (furthermore, the returned data is owned by the config cache, saving us from having to worry about freeing it later). LSAN output from t0001: Direct leak of 73 byte(s) in 1 object(s) allocated from: #0 0x49a859 in realloc /home/abuild/rpmbuild/BUILD/llvm-11.0.0.src/build/../projects/compiler-rt/lib/asan/asan_malloc_linux.cpp:164:3 #1 0x9a7276 in xrealloc /home/ahunt/oss-fuzz/git/wrapper.c:126:8 #2 0x9362ad in strbuf_grow /home/ahunt/oss-fuzz/git/strbuf.c:98:2 #3 0x936eaa in strbuf_add /home/ahunt/oss-fuzz/git/strbuf.c:295:2 #4 0x868112 in strbuf_addstr /home/ahunt/oss-fuzz/git/./strbuf.h:304:2 #5 0x86a8ad in expand_user_path /home/ahunt/oss-fuzz/git/path.c:758:2 #6 0x720bb1 in git_config_pathname /home/ahunt/oss-fuzz/git/config.c:1287:10 #7 0x5960e2 in git_init_db_config /home/ahunt/oss-fuzz/git/builtin/init-db.c:161:11 git#8 0x7255b8 in configset_iter /home/ahunt/oss-fuzz/git/config.c:1982:7 git#9 0x7253fc in repo_config /home/ahunt/oss-fuzz/git/config.c:2311:2 git#10 0x725ca7 in git_config /home/ahunt/oss-fuzz/git/config.c:2399:2 git#11 0x593e8d in create_default_files /home/ahunt/oss-fuzz/git/builtin/init-db.c:225:2 git#12 0x5935c6 in init_db /home/ahunt/oss-fuzz/git/builtin/init-db.c:449:11 git#13 0x59588e in cmd_init_db /home/ahunt/oss-fuzz/git/builtin/init-db.c:714:9 git#14 0x4cd60d in run_builtin /home/ahunt/oss-fuzz/git/git.c:453:11 git#15 0x4cb2da in handle_builtin /home/ahunt/oss-fuzz/git/git.c:704:3 git#16 0x4ccc37 in run_argv /home/ahunt/oss-fuzz/git/git.c:771:4 git#17 0x4cac29 in cmd_main /home/ahunt/oss-fuzz/git/git.c:902:19 git#18 0x69c4de in main /home/ahunt/oss-fuzz/git/common-main.c:52:11 git#19 0x7f23552d6349 in __libc_start_main (/lib64/libc.so.6+0x24349)
1 parent f9d3922 commit a91ef5b

File tree

1 file changed

+5
-14
lines changed

1 file changed

+5
-14
lines changed

builtin/init-db.c

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
static int init_is_bare_repository = 0;
2727
static int init_shared_repository = -1;
28-
static const char *init_db_template_dir;
2928

3029
static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
3130
DIR *dir)
@@ -94,7 +93,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
9493
}
9594
}
9695

97-
static void copy_templates(const char *template_dir)
96+
static void copy_templates(const char *template_dir, const char *init_db_template_dir)
9897
{
9998
struct strbuf path = STRBUF_INIT;
10099
struct strbuf template_path = STRBUF_INIT;
@@ -154,14 +153,6 @@ static void copy_templates(const char *template_dir)
154153
clear_repository_format(&template_format);
155154
}
156155

157-
static int git_init_db_config(const char *k, const char *v, void *cb)
158-
{
159-
if (!strcmp(k, "init.templatedir"))
160-
return git_config_pathname(&init_db_template_dir, k, v);
161-
162-
return 0;
163-
}
164-
165156
/*
166157
* If the git_dir is not directly inside the working tree, then git will not
167158
* find it by default, and we need to set the worktree explicitly.
@@ -209,9 +200,7 @@ static int create_default_files(const char *template_path,
209200
int reinit;
210201
int filemode;
211202
struct strbuf err = STRBUF_INIT;
212-
213-
init_db_template_dir = NULL; /* re-set in case it was set before */
214-
git_config(git_init_db_config, NULL);
203+
const char *init_db_template_dir = NULL;
215204

216205
/*
217206
* First copy the templates -- we might have the default
@@ -222,7 +211,8 @@ static int create_default_files(const char *template_path,
222211
* values (since we've just potentially changed what's available on
223212
* disk).
224213
*/
225-
copy_templates(template_path);
214+
git_config_get_value("init.templatedir", &init_db_template_dir);
215+
copy_templates(template_path, init_db_template_dir);
226216
git_config_clear();
227217
reset_shared_repository();
228218
git_config(git_default_config, NULL);
@@ -696,6 +686,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
696686
UNLEAK(real_git_dir);
697687
UNLEAK(git_dir);
698688
UNLEAK(work_tree);
689+
UNLEAK(template_dir);
699690

700691
flags |= INIT_DB_EXIST_OK;
701692
return init_db(git_dir, real_git_dir, template_dir, hash_algo,

0 commit comments

Comments
 (0)