]> git.ipfire.org Git - thirdparty/git.git/commitdiff
grep: fix racy calls in grep_objects()
authorMatheus Tavares <matheus.bernardino@usp.br>
Thu, 16 Jan 2020 02:39:51 +0000 (23:39 -0300)
committerJunio C Hamano <gitster@pobox.com>
Fri, 17 Jan 2020 21:52:14 +0000 (13:52 -0800)
deref_tag() calls is_promisor_object() and parse_object(), both of which
perform lazy initializations and other thread-unsafe operations. If it
was only called by grep_objects() this wouldn't be a problem as the
latter is only executed by the main thread. However, deref_tag() is also
present in read_object_file()'s call stack. So calling deref_tag() in
grep_objects() without acquiring the grep_read_mutex may incur in a race
condition with object reading operations (such as the ones internally
performed by fill_textconv(), called at fill_textconv_grep()). The same
problem happens with the call to gitmodules_config_oid() which also has
parse_object() in its call stack. Fix that protecting both calls with
the said grep_read_mutex.

Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/grep.c

index 896e7effcea52d65230a2e67dc26a26da98d9cbc..91fc032a324f9bd11bf16ccc4a5dbbc21a905336 100644 (file)
@@ -658,13 +658,18 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
 
        for (i = 0; i < nr; i++) {
                struct object *real_obj;
+
+               grep_read_lock();
                real_obj = deref_tag(opt->repo, list->objects[i].item,
                                     NULL, 0);
+               grep_read_unlock();
 
                /* load the gitmodules file for this rev */
                if (recurse_submodules) {
                        submodule_free(opt->repo);
+                       grep_read_lock();
                        gitmodules_config_oid(&real_obj->oid);
+                       grep_read_unlock();
                }
                if (grep_object(opt, pathspec, real_obj, list->objects[i].name,
                                list->objects[i].path)) {