git@vger.kernel.org list mirror (unofficial, one of many)
 help / color / mirror / code / Atom feed
* [PATCH] list-objects-filter: initialize sub-filter structs
@ 2022-09-22  9:35 Jeff King
  0 siblings, 0 replies; only message in thread
From: Jeff King @ 2022-09-22  9:35 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

Since commit c54980ab83 (list-objects-filter: convert filter_spec to a
strbuf, 2022-09-11), building with SANITIZE=undefined triggers an error
in t5616.

The problem is that we end up with a strbuf that has been
zero-initialized instead of via STRBUF_INIT. Feeding that strbuf to
strbuf_addbuf() in list_objects_filter_copy() means we will call memcpy
like:

   memcpy(some_actual_buffer, NULL, 0);

This works on most systems because we're copying zero bytes, but it is
technically undefined behavior to ever pass NULL to memcpy.

Even though c54980ab83 is where the bug manifests, that is only because
we switched away from a string_list, which is OK with being
zero-initialized (though it may cause other problems by not duplicating
the strings, it happened to be OK in this instance).

The actual bug is caused by the commit before that, 2a01bdedf8
(list-objects-filter: add and use initializers, 2022-09-11). There we
consistently initialize the top-level filter structs, but we forgot the
dynamically allocated ones we stick in filter_options->sub when creating
combined filters.

Note that we need to fix two spots here: where we parse a "combine:"
filter, but also where we transform from a single-filter into a combined
one after seeing multiple "--filter" options. In the second spot, we'll
do some minor refactoring to avoid repeating our very-long array index.

Signed-off-by: Jeff King <peff@peff.net>
---
This is a regression in v2.38.0-rc1. The fix should go on top of
jk/list-objects-filter-cleanup.

Sorry to have missed it before. I was carefully running all of those
commits through SANITIZE=address (because I was worried about missing
exactly this kind of thing), but for some reason I didn't add UBSan.

The existing BUG() I added there didn't catch it either, because the
sub-filter creation doesn't call into parse_list_objects_filter()
directly. We could try to beef that up with more BUG()s, but I don't
think it's worthwhile. The point there is to catch outside callers not
initializing correctly; this was just a bug in the list-objects code
itself.

 list-objects-filter-options.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c
index d46ce4acc4..5339660238 100644
--- a/list-objects-filter-options.c
+++ b/list-objects-filter-options.c
@@ -143,6 +143,7 @@ static int parse_combine_subfilter(
 
 	ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,
 		      filter_options->sub_alloc);
+	list_objects_filter_init(&filter_options->sub[new_index]);
 
 	decoded = url_percent_decode(subspec->buf);
 
@@ -263,6 +264,8 @@ void parse_list_objects_filter(
 		parse_error = gently_parse_list_objects_filter(
 			filter_options, arg, &errbuf);
 	} else {
+		struct list_objects_filter_options *sub;
+
 		/*
 		 * Make filter_options an LOFC_COMBINE spec so we can trivially
 		 * add subspecs to it.
@@ -273,10 +276,11 @@ void parse_list_objects_filter(
 		filter_spec_append_urlencode(filter_options, arg);
 		ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,
 			      filter_options->sub_alloc);
+		sub = &filter_options->sub[filter_options->sub_nr - 1];
 
-		parse_error = gently_parse_list_objects_filter(
-			&filter_options->sub[filter_options->sub_nr - 1], arg,
-			&errbuf);
+		list_objects_filter_init(sub);
+		parse_error = gently_parse_list_objects_filter(sub, arg,
+							       &errbuf);
 	}
 	if (parse_error)
 		die("%s", errbuf.buf);
-- 
@@ -143,6 +143,7 @@ static int parse_combine_subfilter(
 
 	ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,
 		      filter_options->sub_alloc);
+	list_objects_filter_init(&filter_options->sub[new_index]);
 
 	decoded = url_percent_decode(subspec->buf);
 
@@ -263,6 +264,8 @@ void parse_list_objects_filter(
 		parse_error = gently_parse_list_objects_filter(
 			filter_options, arg, &errbuf);
 	} else {
+		struct list_objects_filter_options *sub;
+
 		/*
 		 * Make filter_options an LOFC_COMBINE spec so we can trivially
 		 * add subspecs to it.
@@ -273,10 +276,11 @@ void parse_list_objects_filter(
 		filter_spec_append_urlencode(filter_options, arg);
 		ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,
 			      filter_options->sub_alloc);
+		sub = &filter_options->sub[filter_options->sub_nr - 1];
 
-		parse_error = gently_parse_list_objects_filter(
-			&filter_options->sub[filter_options->sub_nr - 1], arg,
-			&errbuf);
+		list_objects_filter_init(sub);
+		parse_error = gently_parse_list_objects_filter(sub, arg,
+							       &errbuf);
 	}
 	if (parse_error)
 		die("%s", errbuf.buf);
-- 
2.38.0.rc1.583.ga560cd8328

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2022-09-22  9:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-22  9:35 [PATCH] list-objects-filter: initialize sub-filter structs Jeff King

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).