summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Matheus Tavares <matheus.bernardino@usp.br>2020-01-15 23:39:50 -0300
committerLibravatar Junio C Hamano <gitster@pobox.com>2020-01-17 13:52:14 -0800
commitfaf123c730df1a545e2dc7ca82fd437e93fc519c (patch)
treedcf9f0c919620f870de919ce432fc80d2802f23a
parentgrep: fix race conditions on userdiff calls (diff)
downloadtgif-faf123c730df1a545e2dc7ca82fd437e93fc519c.tar.xz
grep: fix race conditions at grep_submodule()
There're currently two function calls in builtin/grep.c:grep_submodule() which might result in race conditions: - submodule_from_path(): it has config_with_options() in its call stack which, in turn, may have read_object_file() in its own. Therefore, calling the first function without acquiring grep_read_mutex may end up causing a race condition with other object read operations performed by worker threads (for example, at the fill_textconv() call in grep.c:fill_textconv_grep()). - parse_object_or_die(): it falls into the same problem, having repo_has_object_file(the_repository, ...) in its call stack. Besides that, parse_object(), which is also called by parse_object_or_die(), is thread-unsafe and also called by object reading functions. It's unlikely to really fall into a data race with these operations as the volume of calls to them is usually very low. But we better protect ourselves against this possibility, anyway. So, to solve these issues, move both of these function calls into the critical section of grep_read_mutex. Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/grep.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/builtin/grep.c b/builtin/grep.c
index 50ce8d9461..896e7effce 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -407,8 +407,7 @@ static int grep_submodule(struct grep_opt *opt,
{
struct repository subrepo;
struct repository *superproject = opt->repo;
- const struct submodule *sub = submodule_from_path(superproject,
- &null_oid, path);
+ const struct submodule *sub;
struct grep_opt subopt;
int hit;
@@ -419,6 +418,7 @@ static int grep_submodule(struct grep_opt *opt,
* object.
*/
grep_read_lock();
+ sub = submodule_from_path(superproject, &null_oid, path);
if (!is_submodule_active(superproject, path)) {
grep_read_unlock();
@@ -455,9 +455,8 @@ static int grep_submodule(struct grep_opt *opt,
unsigned long size;
struct strbuf base = STRBUF_INIT;
- object = parse_object_or_die(oid, oid_to_hex(oid));
-
grep_read_lock();
+ object = parse_object_or_die(oid, oid_to_hex(oid));
data = read_object_with_reference(&subrepo,
&object->oid, tree_type,
&size, NULL);