{"thread":{"id":"58490","subject":"[PATCH] list-objects-filter: initialize sub-filter structs","startedAt":"2022-09-22T09:35:51Z","lastAt":"2022-09-22T09:35:51Z","messageCount":1,"participants":["Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"463430","messageId":"YywsZU9UUoC08UcN@coredump.intra.peff.net","threadId":"58490","inReplyTo":null,"subject":"[PATCH] list-objects-filter: initialize sub-filter structs","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2022-09-22T09:35:33Z","receivedAt":"2022-09-22T09:35:51Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"Since commit c54980ab83 (list-objects-filter: convert filter_spec to a\nstrbuf, 2022-09-11), building with SANITIZE=undefined triggers an error\nin t5616.\n\nThe problem is that we end up with a strbuf that has been\nzero-initialized instead of via STRBUF_INIT. Feeding that strbuf to\nstrbuf_addbuf() in list_objects_filter_copy() means we will call memcpy\nlike:\n\n   memcpy(some_actual_buffer, NULL, 0);\n\nThis works on most systems because we're copying zero bytes, but it is\ntechnically undefined behavior to ever pass NULL to memcpy.\n\nEven though c54980ab83 is where the bug manifests, that is only because\nwe switched away from a string_list, which is OK with being\nzero-initialized (though it may cause other problems by not duplicating\nthe strings, it happened to be OK in this instance).\n\nThe actual bug is caused by the commit before that, 2a01bdedf8\n(list-objects-filter: add and use initializers, 2022-09-11). There we\nconsistently initialize the top-level filter structs, but we forgot the\ndynamically allocated ones we stick in filter_options->sub when creating\ncombined filters.\n\nNote that we need to fix two spots here: where we parse a \"combine:\"\nfilter, but also where we transform from a single-filter into a combined\none after seeing multiple \"--filter\" options. In the second spot, we'll\ndo some minor refactoring to avoid repeating our very-long array index.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nThis is a regression in v2.38.0-rc1. The fix should go on top of\njk/list-objects-filter-cleanup.\n\nSorry to have missed it before. I was carefully running all of those\ncommits through SANITIZE=address (because I was worried about missing\nexactly this kind of thing), but for some reason I didn't add UBSan.\n\nThe existing BUG() I added there didn't catch it either, because the\nsub-filter creation doesn't call into parse_list_objects_filter()\ndirectly. We could try to beef that up with more BUG()s, but I don't\nthink it's worthwhile. The point there is to catch outside callers not\ninitializing correctly; this was just a bug in the list-objects code\nitself.\n\n list-objects-filter-options.c | 10 +++++++---\n 1 file changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/list-objects-filter-options.c b/list-objects-filter-options.c\nindex d46ce4acc4..5339660238 100644\n--- a/list-objects-filter-options.c\n+++ b/list-objects-filter-options.c\n@@ -143,6 +143,7 @@ static int parse_combine_subfilter(\n \n \tALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,\n \t\t      filter_options->sub_alloc);\n+\tlist_objects_filter_init(&filter_options->sub[new_index]);\n \n \tdecoded = url_percent_decode(subspec->buf);\n \n@@ -263,6 +264,8 @@ void parse_list_objects_filter(\n \t\tparse_error = gently_parse_list_objects_filter(\n \t\t\tfilter_options, arg, &errbuf);\n \t} else {\n+\t\tstruct list_objects_filter_options *sub;\n+\n \t\t/*\n \t\t * Make filter_options an LOFC_COMBINE spec so we can trivially\n \t\t * add subspecs to it.\n@@ -273,10 +276,11 @@ void parse_list_objects_filter(\n \t\tfilter_spec_append_urlencode(filter_options, arg);\n \t\tALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,\n \t\t\t      filter_options->sub_alloc);\n+\t\tsub = &filter_options->sub[filter_options->sub_nr - 1];\n \n-\t\tparse_error = gently_parse_list_objects_filter(\n-\t\t\t&filter_options->sub[filter_options->sub_nr - 1], arg,\n-\t\t\t&errbuf);\n+\t\tlist_objects_filter_init(sub);\n+\t\tparse_error = gently_parse_list_objects_filter(sub, arg,\n+\t\t\t\t\t\t\t       &errbuf);\n \t}\n \tif (parse_error)\n \t\tdie(\"%s\", errbuf.buf);\n-- \n2.38.0.rc1.583.ga560cd8328\n"}]}