* [PATCH 0/4] ci: fix windows-build with GCC v12.x @ 2022-05-24 0:23 Johannes Schindelin via GitGitGadget 2022-05-24 0:23 ` [PATCH 1/4] compat/win32/syslog: fix use-after-realloc Johannes Schindelin via GitGitGadget ` (4 more replies) 0 siblings, 5 replies; 23+ messages in thread From: Johannes Schindelin via GitGitGadget @ 2022-05-24 0:23 UTC (permalink / raw) To: git; +Cc: Johannes Schindelin A recent update of GCC in Git for Windows' SDK (a subset of which is used in Git's CI/PR builds) broke the build. These patches address that, and they are based on maint-2.34 (earlier maintenance tracks would have a trivial merge conflict due to 013c7e2b070 (http: drop support for curl < 7.16.0, 2021-07-30) removing support for USE_CURL_MULTI). Johannes Schindelin (4): compat/win32/syslog: fix use-after-realloc nedmalloc: avoid new compile error http.c: avoid danging pointer to local variable `finished` dir.c: avoid "exceeds maximum object size" error with GCC v12.x compat/nedmalloc/nedmalloc.c | 1 - compat/win32/syslog.c | 2 ++ dir.c | 9 +++++++++ http-walker.c | 4 ---- http.c | 15 +++++++-------- http.h | 2 +- 6 files changed, 19 insertions(+), 14 deletions(-) base-commit: 2f0dde7852b7866bb044926f73334ff3fc30654b Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1238%2Fdscho%2Ffix-win-build-with-gcc-12-v1 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1238/dscho/fix-win-build-with-gcc-12-v1 Pull-Request: https://github.com/gitgitgadget/git/pull/1238 -- gitgitgadget ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 1/4] compat/win32/syslog: fix use-after-realloc 2022-05-24 0:23 [PATCH 0/4] ci: fix windows-build with GCC v12.x Johannes Schindelin via GitGitGadget @ 2022-05-24 0:23 ` Johannes Schindelin via GitGitGadget 2022-05-24 12:39 ` Johannes Schindelin 2022-05-24 0:23 ` [PATCH 2/4] nedmalloc: avoid new compile error Johannes Schindelin via GitGitGadget ` (3 subsequent siblings) 4 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin via GitGitGadget @ 2022-05-24 0:23 UTC (permalink / raw) To: git; +Cc: Johannes Schindelin, Johannes Schindelin From: Johannes Schindelin <johannes.schindelin@gmx.de> Git for Windows' SDK recently upgraded to GCC v12.x which points out that the `pos` variable might be used even after the corresponding memory was `realloc()`ed and therefore potentially no longer valid. Since a subset of this SDK is used in Git's CI/PR builds, we need to fix this to continue to be able to benefit from the CI/PR runs. Note: This bug has been with us since 2a6b149c64f6 (mingw: avoid using strbuf in syslog, 2011-10-06), and while it looks tempting to replace the hand-rolled string manipulation with a `strbuf`-based one, that commit's message explains why we cannot do that: The `syslog()` function is called as part of the function in `daemon.c` which is set as the `die()` routine, and since `strbuf_grow()` can call that function if it runs out of memory, this would cause a nasty infinite loop that we do not want to re-introduce. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- compat/win32/syslog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compat/win32/syslog.c b/compat/win32/syslog.c index 161978d720a..1f8d8934cc9 100644 --- a/compat/win32/syslog.c +++ b/compat/win32/syslog.c @@ -43,6 +43,7 @@ void syslog(int priority, const char *fmt, ...) va_end(ap); while ((pos = strstr(str, "%1")) != NULL) { + size_t offset = pos - str; char *oldstr = str; str = realloc(str, st_add(++str_len, 1)); if (!str) { @@ -50,6 +51,7 @@ void syslog(int priority, const char *fmt, ...) warning_errno("realloc failed"); return; } + pos = str + offset; memmove(pos + 2, pos + 1, strlen(pos)); pos[1] = ' '; } -- gitgitgadget ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 1/4] compat/win32/syslog: fix use-after-realloc 2022-05-24 0:23 ` [PATCH 1/4] compat/win32/syslog: fix use-after-realloc Johannes Schindelin via GitGitGadget @ 2022-05-24 12:39 ` Johannes Schindelin 2022-05-24 20:58 ` Junio C Hamano 0 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2022-05-24 12:39 UTC (permalink / raw) To: Johannes Schindelin via GitGitGadget; +Cc: git Hi, On Tue, 24 May 2022, Johannes Schindelin via GitGitGadget wrote: > diff --git a/compat/win32/syslog.c b/compat/win32/syslog.c > index 161978d720a..1f8d8934cc9 100644 > --- a/compat/win32/syslog.c > +++ b/compat/win32/syslog.c > @@ -43,6 +43,7 @@ void syslog(int priority, const char *fmt, ...) > va_end(ap); > > while ((pos = strstr(str, "%1")) != NULL) { > + size_t offset = pos - str; > char *oldstr = str; > str = realloc(str, st_add(++str_len, 1)); Since it has been raised elsewhere: Why is that `++str_len` not turned into an `st_add()`? The commit adding that `st_add()` call (50a6c8efa2b (use st_add and st_mult for allocation size computation, 2016-02-22)) does not really talk about it, but the explanation is simple: Before this `while()` loop, we allocate one more than `str_len` (see compat/win32/syslog.c#L35), and we do that already using `st_add()`, so that the string and the terminating NUL fit into the allocated memory. Therefore, the first time we enter the loop, we know that `++str_len` is safe. Now, in this very line, we then increment `str_len` and then `reallocate` one more than that, again guarding it via `st_add()`. So every subsequent iteration will already have checked that `++str_len` is safe, too. By induction (https://en.wikipedia.org/wiki/Mathematical_induction), it follows that this line is safe, and we do not have to change it to a clunkier two-step assignment where we first use `st_add()` to increment `str_len` and then use `st_add()` to allocate enough memory to also fit the trailing NUL. Now you know, Dscho > if (!str) { > @@ -50,6 +51,7 @@ void syslog(int priority, const char *fmt, ...) > warning_errno("realloc failed"); > return; > } > + pos = str + offset; > memmove(pos + 2, pos + 1, strlen(pos)); > pos[1] = ' '; > } > -- > gitgitgadget > > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/4] compat/win32/syslog: fix use-after-realloc 2022-05-24 12:39 ` Johannes Schindelin @ 2022-05-24 20:58 ` Junio C Hamano 0 siblings, 0 replies; 23+ messages in thread From: Junio C Hamano @ 2022-05-24 20:58 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Johannes Schindelin via GitGitGadget, git Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: >> str = realloc(str, st_add(++str_len, 1)); > > Since it has been raised elsewhere: Why is that `++str_len` not turned > into an `st_add()`? > ... > Now you know, I'd be more worried about a macro looking thing evalutating its parameters more than once, though. But unlike st_addN(), st_add() is an inline function so we do not have to worry about that ;-) >> @@ -50,6 +51,7 @@ void syslog(int priority, const char *fmt, ...) >> warning_errno("realloc failed"); >> return; >> } >> + pos = str + offset; The adjustment using ofs is very much straight-forward. Nicely spotted and nicely corrected. Thanks. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 2/4] nedmalloc: avoid new compile error 2022-05-24 0:23 [PATCH 0/4] ci: fix windows-build with GCC v12.x Johannes Schindelin via GitGitGadget 2022-05-24 0:23 ` [PATCH 1/4] compat/win32/syslog: fix use-after-realloc Johannes Schindelin via GitGitGadget @ 2022-05-24 0:23 ` Johannes Schindelin via GitGitGadget 2022-05-24 8:00 ` Ævar Arnfjörð Bjarmason 2022-05-24 0:23 ` [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` Johannes Schindelin via GitGitGadget ` (2 subsequent siblings) 4 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin via GitGitGadget @ 2022-05-24 0:23 UTC (permalink / raw) To: git; +Cc: Johannes Schindelin, Johannes Schindelin From: Johannes Schindelin <johannes.schindelin@gmx.de> GCC v12.x complains thusly: compat/nedmalloc/nedmalloc.c: In function 'DestroyCaches': compat/nedmalloc/nedmalloc.c:326:12: error: the comparison will always evaluate as 'true' for the address of 'caches' will never be NULL [-Werror=address] 326 | if(p->caches) | ^ compat/nedmalloc/nedmalloc.c:196:22: note: 'caches' declared here 196 | threadcache *caches[THREADCACHEMAXCACHES]; | ^~~~~~ ... and it is correct, of course. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- compat/nedmalloc/nedmalloc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/compat/nedmalloc/nedmalloc.c b/compat/nedmalloc/nedmalloc.c index edb438a7776..2c0ace7075a 100644 --- a/compat/nedmalloc/nedmalloc.c +++ b/compat/nedmalloc/nedmalloc.c @@ -323,7 +323,6 @@ static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned in } static void DestroyCaches(nedpool *p) THROWSPEC { - if(p->caches) { threadcache *tc; int n; -- gitgitgadget ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 2/4] nedmalloc: avoid new compile error 2022-05-24 0:23 ` [PATCH 2/4] nedmalloc: avoid new compile error Johannes Schindelin via GitGitGadget @ 2022-05-24 8:00 ` Ævar Arnfjörð Bjarmason 2022-05-24 15:59 ` René Scharfe 0 siblings, 1 reply; 23+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-05-24 8:00 UTC (permalink / raw) To: Johannes Schindelin via GitGitGadget; +Cc: git, Johannes Schindelin On Tue, May 24 2022, Johannes Schindelin via GitGitGadget wrote: > From: Johannes Schindelin <johannes.schindelin@gmx.de> > > GCC v12.x complains thusly: > > compat/nedmalloc/nedmalloc.c: In function 'DestroyCaches': > compat/nedmalloc/nedmalloc.c:326:12: error: the comparison will always > evaluate as 'true' for the address of 'caches' > will never be NULL [-Werror=address] > 326 | if(p->caches) > | ^ > compat/nedmalloc/nedmalloc.c:196:22: note: 'caches' declared here > 196 | threadcache *caches[THREADCACHEMAXCACHES]; > | ^~~~~~ > > ... and it is correct, of course. > > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > --- > compat/nedmalloc/nedmalloc.c | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/compat/nedmalloc/nedmalloc.c b/compat/nedmalloc/nedmalloc.c > index edb438a7776..2c0ace7075a 100644 > --- a/compat/nedmalloc/nedmalloc.c > +++ b/compat/nedmalloc/nedmalloc.c > @@ -323,7 +323,6 @@ static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned in > } > static void DestroyCaches(nedpool *p) THROWSPEC > { > - if(p->caches) > { > threadcache *tc; > int n; This seems sensible, I thought "why not submit it to upstream", i.e. see: https://github.com/ned14/nedmalloc/blob/master/nedmalloc.c#L1298 But that repository was last updated in 2014, I wonder if it's just because nobody's submitted a patch since then, or if it's inactive. Have you tried making Njall Douglas (the nedmalloc author) aware of this issue? ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/4] nedmalloc: avoid new compile error 2022-05-24 8:00 ` Ævar Arnfjörð Bjarmason @ 2022-05-24 15:59 ` René Scharfe 2022-05-24 20:46 ` Johannes Schindelin 0 siblings, 1 reply; 23+ messages in thread From: René Scharfe @ 2022-05-24 15:59 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason, Johannes Schindelin via GitGitGadget Cc: git, Johannes Schindelin Am 24.05.22 um 10:00 schrieb Ævar Arnfjörð Bjarmason: > > This seems sensible, I thought "why not submit it to upstream", > i.e. see: > https://github.com/ned14/nedmalloc/blob/master/nedmalloc.c#L1298 > > But that repository was last updated in 2014, I wonder if it's just > because nobody's submitted a patch since then, or if it's inactive. Have > you tried making Njall Douglas (the nedmalloc author) aware of this > issue? > https://github.com/ned14/nedmalloc says at the top: "This repository has been archived by the owner. It is now read-only.". René ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/4] nedmalloc: avoid new compile error 2022-05-24 15:59 ` René Scharfe @ 2022-05-24 20:46 ` Johannes Schindelin 2022-05-24 21:33 ` Ævar Arnfjörð Bjarmason 0 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2022-05-24 20:46 UTC (permalink / raw) To: René Scharfe Cc: Ævar Arnfjörð Bjarmason, Johannes Schindelin via GitGitGadget, git [-- Attachment #1: Type: text/plain, Size: 997 bytes --] Hi René, On Tue, 24 May 2022, René Scharfe wrote: > Am 24.05.22 um 10:00 schrieb Ævar Arnfjörð Bjarmason: > > > > This seems sensible, I thought "why not submit it to upstream", > > i.e. see: > > https://github.com/ned14/nedmalloc/blob/master/nedmalloc.c#L1298 > > > > But that repository was last updated in 2014, I wonder if it's just > > because nobody's submitted a patch since then, or if it's inactive. Have > > you tried making Njall Douglas (the nedmalloc author) aware of this > > issue? > > > > https://github.com/ned14/nedmalloc says at the top: "This repository has > been archived by the owner. It is now read-only.". Indeed, maintenance of nedmalloc has stopped a few years ago (see e.g. https://github.com/ned14/nedmalloc/issues/20#issuecomment-343432314). About five years ago I tried to upgrade us to the latest nedmalloc version but ran into a performance regression that I was unable to justify the time to investigate further. Ciao, Dscho ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/4] nedmalloc: avoid new compile error 2022-05-24 20:46 ` Johannes Schindelin @ 2022-05-24 21:33 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 23+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-05-24 21:33 UTC (permalink / raw) To: Johannes Schindelin Cc: René Scharfe, Johannes Schindelin via GitGitGadget, git On Tue, May 24 2022, Johannes Schindelin wrote: > Hi René, > > On Tue, 24 May 2022, René Scharfe wrote: > >> Am 24.05.22 um 10:00 schrieb Ævar Arnfjörð Bjarmason: >> > >> > This seems sensible, I thought "why not submit it to upstream", >> > i.e. see: >> > https://github.com/ned14/nedmalloc/blob/master/nedmalloc.c#L1298 >> > >> > But that repository was last updated in 2014, I wonder if it's just >> > because nobody's submitted a patch since then, or if it's inactive. Have >> > you tried making Njall Douglas (the nedmalloc author) aware of this >> > issue? >> > >> >> https://github.com/ned14/nedmalloc says at the top: "This repository has >> been archived by the owner. It is now read-only.". > > Indeed, maintenance of nedmalloc has stopped a few years ago (see e.g. > https://github.com/ned14/nedmalloc/issues/20#issuecomment-343432314). The author says: nedmalloc is pretty much EOL. Happy to accept patches, but unwilling to fix. The "Happy to accept patches" seems to suggest that they're willing to take a PR, just not willing to do spend time on it themselves. Anyway, I see that we've accumulated quite a few patches on top, and given... > About five years ago I tried to upgrade us to the latest nedmalloc version > but ran into a performance regression that I was unable to justify the > time to investigate further. ...perhaps it's not worth it. Maybe someone should get to updating the readme we carry from it to change the first line from: nedalloc v1.05 15th June 2008: To: Git's (perma-)fork & local hacks on top of nedalloc v1.05 15th June 2008: Or something :) ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` 2022-05-24 0:23 [PATCH 0/4] ci: fix windows-build with GCC v12.x Johannes Schindelin via GitGitGadget 2022-05-24 0:23 ` [PATCH 1/4] compat/win32/syslog: fix use-after-realloc Johannes Schindelin via GitGitGadget 2022-05-24 0:23 ` [PATCH 2/4] nedmalloc: avoid new compile error Johannes Schindelin via GitGitGadget @ 2022-05-24 0:23 ` Johannes Schindelin via GitGitGadget 2022-05-24 7:58 ` Ævar Arnfjörð Bjarmason 2022-05-24 0:23 ` [PATCH 4/4] dir.c: avoid "exceeds maximum object size" error with GCC v12.x Johannes Schindelin via GitGitGadget 2022-05-24 15:54 ` [PATCH 0/4] ci: fix windows-build " Jeff Hostetler 4 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin via GitGitGadget @ 2022-05-24 0:23 UTC (permalink / raw) To: git; +Cc: Johannes Schindelin, Johannes Schindelin From: Johannes Schindelin <johannes.schindelin@gmx.de> In http.c, the run_active_slot() function allows the given "slot" to make progress by calling step_active_slots() in a loop repeatedly, and the loop is not left until the request held in the slot completes. Ages ago, we used to use the slot->in_use member to get out of the loop, which misbehaved when the request in "slot" completes (at which time, the result of the request is copied away from the slot, and the in_use member is cleared, making the slot ready to be reused), and the "slot" gets reused to service a different request (at which time, the "slot" becomes in_use again, even though it is for a different request). The loop terminating condition mistakenly thought that the original request has yet to be completed. Today's code, after baa7b67d (HTTP slot reuse fixes, 2006-03-10) fixed this issue, uses a separate "slot->finished" member that is set in run_active_slot() to point to an on-stack variable, and the code that completes the request in finish_active_slot() clears the on-stack variable via the pointer to signal that the particular request held by the slot has completed. It also clears the in_use member (as before that fix), so that the slot itself can safely be reused for an unrelated request. One thing that is not quite clean in this arrangement is that, unless the slot gets reused, at which point the finished member is reset to NULL, the member keeps the value of &finished, which becomes a dangling pointer into the stack when run_active_slot() returns. Let's drop that local variable and introduce a new flag in the slot that is used to indicate that even while the slot is no longer in use, it is still reserved until further notice. It is the responsibility of `run_active_slot()` to clear that flag once it is done with that slot. Initial-patch-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- http-walker.c | 4 ---- http.c | 15 +++++++-------- http.h | 2 +- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/http-walker.c b/http-walker.c index 910fae539b8..5cc369dea85 100644 --- a/http-walker.c +++ b/http-walker.c @@ -225,13 +225,9 @@ static void process_alternates_response(void *callback_data) alt_req->url->buf); active_requests++; slot->in_use = 1; - if (slot->finished != NULL) - (*slot->finished) = 0; if (!start_active_slot(slot)) { cdata->got_alternates = -1; slot->in_use = 0; - if (slot->finished != NULL) - (*slot->finished) = 1; } return; } diff --git a/http.c b/http.c index f92859f43fa..00206676597 100644 --- a/http.c +++ b/http.c @@ -197,8 +197,7 @@ static void finish_active_slot(struct active_request_slot *slot) closedown_active_slot(slot); curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code); - if (slot->finished != NULL) - (*slot->finished) = 1; + slot->in_use = 0; /* Store slot results so they can be read after the slot is reused */ if (slot->results != NULL) { @@ -1176,13 +1175,14 @@ struct active_request_slot *get_active_slot(void) process_curl_messages(); } - while (slot != NULL && slot->in_use) + while (slot != NULL && (slot->in_use || slot->reserved_for_use)) slot = slot->next; if (slot == NULL) { newslot = xmalloc(sizeof(*newslot)); newslot->curl = NULL; newslot->in_use = 0; + newslot->reserved_for_use = 0; newslot->next = NULL; slot = active_queue_head; @@ -1204,7 +1204,6 @@ struct active_request_slot *get_active_slot(void) active_requests++; slot->in_use = 1; slot->results = NULL; - slot->finished = NULL; slot->callback_data = NULL; slot->callback_func = NULL; curl_easy_setopt(slot->curl, CURLOPT_COOKIEFILE, curl_cookie_file); @@ -1296,7 +1295,7 @@ void fill_active_slots(void) } while (slot != NULL) { - if (!slot->in_use && slot->curl != NULL + if (!slot->in_use && !slot->reserved_for_use && slot->curl && curl_session_count > min_curl_sessions) { curl_easy_cleanup(slot->curl); slot->curl = NULL; @@ -1327,10 +1326,9 @@ void run_active_slot(struct active_request_slot *slot) fd_set excfds; int max_fd; struct timeval select_timeout; - int finished = 0; - slot->finished = &finished; - while (!finished) { + slot->reserved_for_use = 1; + while (slot->in_use) { step_active_slots(); if (slot->in_use) { @@ -1367,6 +1365,7 @@ void run_active_slot(struct active_request_slot *slot) select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout); } } + slot->reserved_for_use = 0; } static void release_active_slot(struct active_request_slot *slot) diff --git a/http.h b/http.h index df1590e53a4..3b2f6da570c 100644 --- a/http.h +++ b/http.h @@ -22,9 +22,9 @@ struct slot_results { struct active_request_slot { CURL *curl; int in_use; + int reserved_for_use; CURLcode curl_result; long http_code; - int *finished; struct slot_results *results; void *callback_data; void (*callback_func)(void *data); -- gitgitgadget ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` 2022-05-24 0:23 ` [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` Johannes Schindelin via GitGitGadget @ 2022-05-24 7:58 ` Ævar Arnfjörð Bjarmason 2022-05-24 20:06 ` Junio C Hamano 0 siblings, 1 reply; 23+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-05-24 7:58 UTC (permalink / raw) To: Johannes Schindelin via GitGitGadget; +Cc: git, Johannes Schindelin On Tue, May 24 2022, Johannes Schindelin via GitGitGadget wrote: > From: Johannes Schindelin <johannes.schindelin@gmx.de> > [...] > Let's drop that local variable and introduce a new flag in the slot that > is used to indicate that even while the slot is no longer in use, it is > still reserved until further notice. It is the responsibility of > `run_active_slot()` to clear that flag once it is done with that slot. > > Initial-patch-by: Junio C Hamano <gitster@pobox.com> Don't you mean by me? I.e. https://lore.kernel.org/git/patch-1.1-1cec367e805-20220126T212921Z-avarab@gmail.com/ This seems to be derived from that, or perhaps you just came up with something similar independently. Junio then came up with the smaller https://lore.kernel.org/git/xmqq8rv2nggn.fsf@gitster.g/ ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` 2022-05-24 7:58 ` Ævar Arnfjörð Bjarmason @ 2022-05-24 20:06 ` Junio C Hamano 2022-05-24 21:15 ` Johannes Schindelin 0 siblings, 1 reply; 23+ messages in thread From: Junio C Hamano @ 2022-05-24 20:06 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason Cc: Johannes Schindelin via GitGitGadget, git, Johannes Schindelin Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > On Tue, May 24 2022, Johannes Schindelin via GitGitGadget wrote: > >> From: Johannes Schindelin <johannes.schindelin@gmx.de> >> [...] >> Let's drop that local variable and introduce a new flag in the slot that >> is used to indicate that even while the slot is no longer in use, it is >> still reserved until further notice. It is the responsibility of >> `run_active_slot()` to clear that flag once it is done with that slot. >> >> Initial-patch-by: Junio C Hamano <gitster@pobox.com> > > Don't you mean by me? > I.e. https://lore.kernel.org/git/patch-1.1-1cec367e805-20220126T212921Z-avarab@gmail.com/ Most likely, but this version is so distant from the "clear slot->finished before leaving run_active_slot()" Dscho and I were recently discussing, that I do not think it can be said to have been derived from that one. This is completely a different patch that makes different changes. The "clear slot->finished", by the way, is what I think is the right thing to do, especially that the objective is to squelch the false positive warning from a new compiler. If there is a way to annotate the line for the compiler to tell it not to warn about it, that would have been even better. > This seems to be derived from that, or perhaps you just came up with > something similar independently. Junio then came up with the smaller > https://lore.kernel.org/git/xmqq8rv2nggn.fsf@gitster.g/ I actually do not think so. Yours is revert of the existing fix the compiler is confused about, and I have a feeling that if the original fix is still relevant, the problem the original fix wanted to address will resurface as a regression. If I am reading the patch correctly, Dscho's is to avoid [*] reusing a slot while any run_active_slot() is still waiting for its completion. The approach would solve the problem the original fix wanted to solve in a different way. Personally I do not think such a surgery is necessary only to squelch false positives from a new warning compiler, though. [Footnote] * I said "is to avoid", not "avoids", because I haven't studied the patch with sufficient degree of carefulness to say for sure, even though I can see that is the intent. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` 2022-05-24 20:06 ` Junio C Hamano @ 2022-05-24 21:15 ` Johannes Schindelin 2022-05-24 21:45 ` Ævar Arnfjörð Bjarmason 2022-05-24 22:38 ` Junio C Hamano 0 siblings, 2 replies; 23+ messages in thread From: Johannes Schindelin @ 2022-05-24 21:15 UTC (permalink / raw) To: Junio C Hamano Cc: Ævar Arnfjörð Bjarmason, Johannes Schindelin via GitGitGadget, git Hi Junio, On Tue, 24 May 2022, Junio C Hamano wrote: > The "clear slot->finished", by the way, is what I think is the right > thing to do, especially that the objective is to squelch the false > positive warning from a new compiler. If there is a way to annotate > the line for the compiler to tell it not to warn about it, that would > have been even better. We could do something like this: -- snip -- diff --git a/http.c b/http.c index b08795715f8a..2ac8d51d3668 100644 --- a/http.c +++ b/http.c @@ -1365,7 +1365,14 @@ void run_active_slot(struct active_request_slot *slot) struct timeval select_timeout; int finished = 0; +#if __GNUC__ >= 12 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdangling-pointer" +#endif slot->finished = &finished; +#if __GNUC__ >= 12 +#pragma GCC diagnostic pop +#endif while (!finished) { step_active_slots(); -- snap -- That's quite ugly, though. And what's worse, it is pretty unreadable, too. Ciao, Dscho ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` 2022-05-24 21:15 ` Johannes Schindelin @ 2022-05-24 21:45 ` Ævar Arnfjörð Bjarmason 2022-05-24 22:38 ` Junio C Hamano 1 sibling, 0 replies; 23+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-05-24 21:45 UTC (permalink / raw) To: Johannes Schindelin Cc: Junio C Hamano, Johannes Schindelin via GitGitGadget, git On Tue, May 24 2022, Johannes Schindelin wrote: > Hi Junio, > > On Tue, 24 May 2022, Junio C Hamano wrote: > >> The "clear slot->finished", by the way, is what I think is the right >> thing to do, especially that the objective is to squelch the false >> positive warning from a new compiler. If there is a way to annotate >> the line for the compiler to tell it not to warn about it, that would >> have been even better. > > We could do something like this: > > -- snip -- > diff --git a/http.c b/http.c > index b08795715f8a..2ac8d51d3668 100644 > --- a/http.c > +++ b/http.c > @@ -1365,7 +1365,14 @@ void run_active_slot(struct active_request_slot *slot) > struct timeval select_timeout; > int finished = 0; > > +#if __GNUC__ >= 12 > +#pragma GCC diagnostic push > +#pragma GCC diagnostic ignored "-Wdangling-pointer" > +#endif > slot->finished = &finished; > +#if __GNUC__ >= 12 > +#pragma GCC diagnostic pop > +#endif > while (!finished) { > step_active_slots(); > -- snap -- > > That's quite ugly, though. And what's worse, it is pretty unreadable, too. Unfortunately that sort of thing is a logic error as clang, ICC and probably others are on a mission to make __GNUC__ as useless as possible: https://stackoverflow.com/questions/38499462/how-to-tell-clang-to-stop-pretending-to-be-other-compilers I think it *might* work in practice though, my local clang claims to be gcc 4, so maybe everyone faking it stops at a low enough version? But did you spot 9c539d1027d (config.mak.dev: alternative workaround to gcc 12 warning in http.c, 2022-04-15)? We already disable this file-wide in config.mak.dev, but I didn't check if the Windows code was using that (or if you were targeting those without DEVELOPER=1). We could move that to thake main Makefile, but then we'd have to call detect-compiler there. I have some local patches to do something like that if there's interest (rather, to bootstrap compilation by compiling a C object and getting the macro values, instead of relying on that shellscript). ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` 2022-05-24 21:15 ` Johannes Schindelin 2022-05-24 21:45 ` Ævar Arnfjörð Bjarmason @ 2022-05-24 22:38 ` Junio C Hamano 2022-05-25 10:16 ` Johannes Schindelin 1 sibling, 1 reply; 23+ messages in thread From: Junio C Hamano @ 2022-05-24 22:38 UTC (permalink / raw) To: Johannes Schindelin Cc: Ævar Arnfjörð Bjarmason, Johannes Schindelin via GitGitGadget, git Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > Hi Junio, > > On Tue, 24 May 2022, Junio C Hamano wrote: > >> The "clear slot->finished", by the way, is what I think is the right >> thing to do, especially that the objective is to squelch the false >> positive warning from a new compiler. If there is a way to annotate >> the line for the compiler to tell it not to warn about it, that would >> have been even better. > > We could do something like this: Yuck. > -- snip -- > diff --git a/http.c b/http.c > index b08795715f8a..2ac8d51d3668 100644 > --- a/http.c > +++ b/http.c > @@ -1365,7 +1365,14 @@ void run_active_slot(struct active_request_slot *slot) > struct timeval select_timeout; > int finished = 0; > > +#if __GNUC__ >= 12 > +#pragma GCC diagnostic push > +#pragma GCC diagnostic ignored "-Wdangling-pointer" > +#endif > slot->finished = &finished; > +#if __GNUC__ >= 12 > +#pragma GCC diagnostic pop > +#endif > while (!finished) { > step_active_slots(); > -- snap -- > > That's quite ugly, though. And what's worse, it is pretty unreadable, too. Yes, very ugly. Would an unconditional slot->finished = NULL; at the end squelch the warning? Or there is a way to say "we make all warnings into errors with -Werror, but we do not want to turn this dangling-pointer warning to an error, because it has false positives"? Or we could add "-Wno-dangling-pointer" globally, perhaps. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` 2022-05-24 22:38 ` Junio C Hamano @ 2022-05-25 10:16 ` Johannes Schindelin 2022-05-25 12:48 ` Ævar Arnfjörð Bjarmason 0 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2022-05-25 10:16 UTC (permalink / raw) To: Junio C Hamano Cc: Ævar Arnfjörð Bjarmason, Johannes Schindelin via GitGitGadget, git Hi Junio, On Tue, 24 May 2022, Junio C Hamano wrote: > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > > > On Tue, 24 May 2022, Junio C Hamano wrote: > > > >> The "clear slot->finished", by the way, is what I think is the right > >> thing to do, especially that the objective is to squelch the false > >> positive warning from a new compiler. If there is a way to annotate > >> the line for the compiler to tell it not to warn about it, that would > >> have been even better. > > > > We could do something like this: > > Yuck. > > > -- snip -- > > diff --git a/http.c b/http.c > > index b08795715f8a..2ac8d51d3668 100644 > > --- a/http.c > > +++ b/http.c > > @@ -1365,7 +1365,14 @@ void run_active_slot(struct active_request_slot *slot) > > struct timeval select_timeout; > > int finished = 0; > > > > +#if __GNUC__ >= 12 > > +#pragma GCC diagnostic push > > +#pragma GCC diagnostic ignored "-Wdangling-pointer" > > +#endif > > slot->finished = &finished; > > +#if __GNUC__ >= 12 > > +#pragma GCC diagnostic pop > > +#endif > > while (!finished) { > > step_active_slots(); > > -- snap -- > > > > That's quite ugly, though. And what's worse, it is pretty unreadable, too. > > Yes, very ugly. Would an unconditional > > slot->finished = NULL; > > at the end squelch the warning? No, unfortunately not: https://github.com/dscho/git/actions/runs/2383492484 As you mentioned elsewhere, the error is clearly about the assignment in the first place, and it does not matter that the function will rectify the situation. It's the correct thing to do for the compiler, too: since `slot->finished` already has the pointer, and since the `active_request_slot` struct is declared globally, code outside the current file might squirrel that pointer away for later use. > Or there is a way to say "we make all warnings into errors with > -Werror, but we do not want to turn this dangling-pointer warning to > an error, because it has false positives"? > > Or we could add "-Wno-dangling-pointer" globally, perhaps. I'd like to avoid that because it would quite likely hide legitimate issues elsewhere. It currently seems to be the easiest solution to simply turn the local variable into a heap variable: -- snip -- diff --git a/http.c b/http.c index f92859f43fa..0712debd558 100644 --- a/http.c +++ b/http.c @@ -1327,10 +1327,10 @@ void run_active_slot(struct active_request_slot *slot) fd_set excfds; int max_fd; struct timeval select_timeout; - int finished = 0; + int *finished = xcalloc(1, sizeof(int)); - slot->finished = &finished; - while (!finished) { + slot->finished = finished; + while (!*finished) { step_active_slots(); if (slot->in_use) { @@ -1367,6 +1367,9 @@ void run_active_slot(struct active_request_slot *slot) select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout); } } + if (slot->finished == finished) + slot->finished = NULL; + free(finished); } static void release_active_slot(struct active_request_slot *slot) -- snap -- This pacifies GCC (https://github.com/dscho/git/runs/6589617700) and is the most minimally-intrusive work-around of which I am currently aware. Ciao, Dscho ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` 2022-05-25 10:16 ` Johannes Schindelin @ 2022-05-25 12:48 ` Ævar Arnfjörð Bjarmason 0 siblings, 0 replies; 23+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-05-25 12:48 UTC (permalink / raw) To: Johannes Schindelin Cc: Junio C Hamano, Johannes Schindelin via GitGitGadget, git On Wed, May 25 2022, Johannes Schindelin wrote: > Hi Junio, > > On Tue, 24 May 2022, Junio C Hamano wrote: > >> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: >> >> > On Tue, 24 May 2022, Junio C Hamano wrote: >> > >> >> The "clear slot->finished", by the way, is what I think is the right >> >> thing to do, especially that the objective is to squelch the false >> >> positive warning from a new compiler. If there is a way to annotate >> >> the line for the compiler to tell it not to warn about it, that would >> >> have been even better. >> > >> > We could do something like this: >> >> Yuck. >> >> > -- snip -- >> > diff --git a/http.c b/http.c >> > index b08795715f8a..2ac8d51d3668 100644 >> > --- a/http.c >> > +++ b/http.c >> > @@ -1365,7 +1365,14 @@ void run_active_slot(struct active_request_slot *slot) >> > struct timeval select_timeout; >> > int finished = 0; >> > >> > +#if __GNUC__ >= 12 >> > +#pragma GCC diagnostic push >> > +#pragma GCC diagnostic ignored "-Wdangling-pointer" >> > +#endif >> > slot->finished = &finished; >> > +#if __GNUC__ >= 12 >> > +#pragma GCC diagnostic pop >> > +#endif >> > while (!finished) { >> > step_active_slots(); >> > -- snap -- >> > >> > That's quite ugly, though. And what's worse, it is pretty unreadable, too. >> >> Yes, very ugly. Would an unconditional >> >> slot->finished = NULL; >> >> at the end squelch the warning? > > No, unfortunately not: > https://github.com/dscho/git/actions/runs/2383492484 Yes it does. Didn't you just have a PBCAK between writing that test & pushing it? Your https://github.com/dscho/git/blob/tmp/http.c#L1370-L1371 shows that you didn't make that edit. This on top of "seen" makes the warning go away: - if (slot->finished == &finished) - slot->finished = NULL; + slot->finished = NULL; This is also all covered in the initial thread from back in January, which if you're slowly re-discovering the learnings from there I encourage you to read in more detail... :) > As you mentioned elsewhere, the error is clearly about the assignment in > the first place, and it does not matter that the function will rectify the > situation. It's the correct thing to do for the compiler, too: since > `slot->finished` already has the pointer, and since the > `active_request_slot` struct is declared globally, code outside the > current file might squirrel that pointer away for later use. Per the above this isn't true, and in some side-thread replies (and in the initial thread) I've linked to the GCC code in question. NULL-ing the slot is sufficient, it doesn't matter that the struct it's in survives the function, just that the pointer isn't exposed. >> Or there is a way to say "we make all warnings into errors with >> -Werror, but we do not want to turn this dangling-pointer warning to >> an error, because it has false positives"? >> >> Or we could add "-Wno-dangling-pointer" globally, perhaps. > > I'd like to avoid that because it would quite likely hide legitimate > issues elsewhere. > > It currently seems to be the easiest solution to simply turn the local > variable into a heap variable: > > -- snip -- > diff --git a/http.c b/http.c > index f92859f43fa..0712debd558 100644 > --- a/http.c > +++ b/http.c > @@ -1327,10 +1327,10 @@ void run_active_slot(struct active_request_slot *slot) > fd_set excfds; > int max_fd; > struct timeval select_timeout; > - int finished = 0; > + int *finished = xcalloc(1, sizeof(int)); > > - slot->finished = &finished; > - while (!finished) { > + slot->finished = finished; > + while (!*finished) { > step_active_slots(); > > if (slot->in_use) { > @@ -1367,6 +1367,9 @@ void run_active_slot(struct active_request_slot *slot) > select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout); > } > } > + if (slot->finished == finished) > + slot->finished = NULL; > + free(finished); > } Also, if we were going to tweak this extensively I'd think this slightly larger POC patch would be a better direction, i.e. we don't need a pointer at all, we're just (ab)using it for a tri-state NULL/0/1, why not just use an enum? I think the "if it's what we just set it to" is just cargo-culting, is there anything to show that run_active_slot() is reentrant? Wouldn't we be better off with a static variable + BUG() that we increment/decremant and panic if it's anything but 0 and 1 if we'd like to add paranoia around that? diff --git a/http-walker.c b/http-walker.c index b8f0f98ae14..26184a82ddb 100644 --- a/http-walker.c +++ b/http-walker.c @@ -225,13 +225,13 @@ static void process_alternates_response(void *callback_data) alt_req->url->buf); active_requests++; slot->in_use = 1; - if (slot->finished) - (*slot->finished) = 0; + if (slot->f != FIN_UNSET) + slot->f = FIN_NO; if (!start_active_slot(slot)) { cdata->got_alternates = -1; slot->in_use = 0; - if (slot->finished) - (*slot->finished) = 1; + if (slot->f != FIN_UNSET) + slot->f = FIN_YES; } return; } diff --git a/http.c b/http.c index b148468b267..845dd40768c 100644 --- a/http.c +++ b/http.c @@ -197,8 +197,8 @@ static void finish_active_slot(struct active_request_slot *slot) closedown_active_slot(slot); curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code); - if (slot->finished) - (*slot->finished) = 1; + if (slot->f != FIN_UNSET) + slot->f = FIN_YES; /* Store slot results so they can be read after the slot is reused */ if (slot->results) { @@ -1204,7 +1204,7 @@ struct active_request_slot *get_active_slot(void) active_requests++; slot->in_use = 1; slot->results = NULL; - slot->finished = NULL; + slot->f = FIN_UNSET; slot->callback_data = NULL; slot->callback_func = NULL; curl_easy_setopt(slot->curl, CURLOPT_COOKIEFILE, curl_cookie_file); @@ -1327,10 +1327,9 @@ void run_active_slot(struct active_request_slot *slot) fd_set excfds; int max_fd; struct timeval select_timeout; - int finished = 0; - slot->finished = &finished; - while (!finished) { + slot->f = FIN_NO; + while (slot->f == FIN_NO) { step_active_slots(); if (slot->in_use) { diff --git a/http.h b/http.h index df1590e53a4..fc664d90bc9 100644 --- a/http.h +++ b/http.h @@ -19,12 +19,13 @@ struct slot_results { long http_connectcode; }; +enum fin { FIN_UNSET, FIN_NO, FIN_YES }; struct active_request_slot { CURL *curl; int in_use; CURLcode curl_result; long http_code; - int *finished; + enum fin f; struct slot_results *results; void *callback_data; void (*callback_func)(void *data); ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 4/4] dir.c: avoid "exceeds maximum object size" error with GCC v12.x 2022-05-24 0:23 [PATCH 0/4] ci: fix windows-build with GCC v12.x Johannes Schindelin via GitGitGadget ` (2 preceding siblings ...) 2022-05-24 0:23 ` [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` Johannes Schindelin via GitGitGadget @ 2022-05-24 0:23 ` Johannes Schindelin via GitGitGadget 2022-05-24 5:53 ` Ævar Arnfjörð Bjarmason 2022-05-24 15:54 ` [PATCH 0/4] ci: fix windows-build " Jeff Hostetler 4 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin via GitGitGadget @ 2022-05-24 0:23 UTC (permalink / raw) To: git; +Cc: Johannes Schindelin, Johannes Schindelin From: Johannes Schindelin <johannes.schindelin@gmx.de> Technically, the pointer difference `end - start` _could_ be negative, and when cast to an (unsigned) `size_t` that would cause problems. In this instance, the symptom is: dir.c: In function 'git_url_basename': dir.c:3087:13: error: 'memchr' specified bound [9223372036854775808, 0] exceeds maximum object size 9223372036854775807 [-Werror=stringop-overread] CC ewah/bitmap.o 3087 | if (memchr(start, '/', end - start) == NULL | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ While it is a bit far-fetched to think that `end` (which is defined as `repo + strlen(repo)`) and `start` (which starts at `repo` and never steps beyond the NUL terminator) could result in such a negative difference, GCC has no way of knowing that. See also https://gcc.gnu.org/bugzilla//show_bug.cgi?id=85783. Let's just add a safety check, primarily for GCC's benefit. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- dir.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dir.c b/dir.c index 5aa6fbad0b7..ea78f606230 100644 --- a/dir.c +++ b/dir.c @@ -3076,6 +3076,15 @@ char *git_url_basename(const char *repo, int is_bundle, int is_bare) end--; } + /* + * It should not be possible to overflow `ptrdiff_t` by passing in an + * insanely long URL, but GCC does not know that and will complain + * without this check. + */ + if (end - start < 0) + die(_("No directory name could be guessed.\n" + "Please specify a directory on the command line")); + /* * Strip trailing port number if we've got only a * hostname (that is, there is no dir separator but a -- gitgitgadget ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 4/4] dir.c: avoid "exceeds maximum object size" error with GCC v12.x 2022-05-24 0:23 ` [PATCH 4/4] dir.c: avoid "exceeds maximum object size" error with GCC v12.x Johannes Schindelin via GitGitGadget @ 2022-05-24 5:53 ` Ævar Arnfjörð Bjarmason 2022-05-24 21:05 ` Johannes Schindelin 0 siblings, 1 reply; 23+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2022-05-24 5:53 UTC (permalink / raw) To: Johannes Schindelin via GitGitGadget; +Cc: git, Johannes Schindelin On Tue, May 24 2022, Johannes Schindelin via GitGitGadget wrote: > From: Johannes Schindelin <johannes.schindelin@gmx.de> > > Technically, the pointer difference `end - start` _could_ be negative, > and when cast to an (unsigned) `size_t` that would cause problems. In > this instance, the symptom is: > > dir.c: In function 'git_url_basename': > dir.c:3087:13: error: 'memchr' specified bound [9223372036854775808, 0] > exceeds maximum object size 9223372036854775807 > [-Werror=stringop-overread] > CC ewah/bitmap.o > 3087 | if (memchr(start, '/', end - start) == NULL > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > While it is a bit far-fetched to think that `end` (which is defined as > `repo + strlen(repo)`) and `start` (which starts at `repo` and never > steps beyond the NUL terminator) could result in such a negative > difference, GCC has no way of knowing that. > > See also https://gcc.gnu.org/bugzilla//show_bug.cgi?id=85783. > > Let's just add a safety check, primarily for GCC's benefit. > > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > --- > dir.c | 9 +++++++++ > 1 file changed, 9 insertions(+) > > diff --git a/dir.c b/dir.c > index 5aa6fbad0b7..ea78f606230 100644 > --- a/dir.c > +++ b/dir.c > @@ -3076,6 +3076,15 @@ char *git_url_basename(const char *repo, int is_bundle, int is_bare) > end--; > } > > + /* > + * It should not be possible to overflow `ptrdiff_t` by passing in an > + * insanely long URL, but GCC does not know that and will complain > + * without this check. > + */ > + if (end - start < 0) > + die(_("No directory name could be guessed.\n" This should start with a lower-case letter, see CodingGuidelines. > + "Please specify a directory on the command line")); > + > /* > * Strip trailing port number if we've got only a > * hostname (that is, there is no dir separator but a ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 4/4] dir.c: avoid "exceeds maximum object size" error with GCC v12.x 2022-05-24 5:53 ` Ævar Arnfjörð Bjarmason @ 2022-05-24 21:05 ` Johannes Schindelin 2022-05-25 13:39 ` Derrick Stolee 0 siblings, 1 reply; 23+ messages in thread From: Johannes Schindelin @ 2022-05-24 21:05 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason Cc: Johannes Schindelin via GitGitGadget, git [-- Attachment #1: Type: text/plain, Size: 2489 bytes --] Hi Ævar, On Tue, 24 May 2022, Ævar Arnfjörð Bjarmason wrote: > > On Tue, May 24 2022, Johannes Schindelin via GitGitGadget wrote: > > > From: Johannes Schindelin <johannes.schindelin@gmx.de> > > > > Technically, the pointer difference `end - start` _could_ be negative, > > and when cast to an (unsigned) `size_t` that would cause problems. In > > this instance, the symptom is: > > > > dir.c: In function 'git_url_basename': > > dir.c:3087:13: error: 'memchr' specified bound [9223372036854775808, 0] > > exceeds maximum object size 9223372036854775807 > > [-Werror=stringop-overread] > > CC ewah/bitmap.o > > 3087 | if (memchr(start, '/', end - start) == NULL > > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > While it is a bit far-fetched to think that `end` (which is defined as > > `repo + strlen(repo)`) and `start` (which starts at `repo` and never > > steps beyond the NUL terminator) could result in such a negative > > difference, GCC has no way of knowing that. > > > > See also https://gcc.gnu.org/bugzilla//show_bug.cgi?id=85783. > > > > Let's just add a safety check, primarily for GCC's benefit. > > > > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > > --- > > dir.c | 9 +++++++++ > > 1 file changed, 9 insertions(+) > > > > diff --git a/dir.c b/dir.c > > index 5aa6fbad0b7..ea78f606230 100644 > > --- a/dir.c > > +++ b/dir.c > > @@ -3076,6 +3076,15 @@ char *git_url_basename(const char *repo, int is_bundle, int is_bare) > > end--; > > } > > > > + /* > > + * It should not be possible to overflow `ptrdiff_t` by passing in an > > + * insanely long URL, but GCC does not know that and will complain > > + * without this check. > > + */ > > + if (end - start < 0) > > + die(_("No directory name could be guessed.\n" > > This should start with a lower-case letter, see CodingGuidelines. This message is copied from existing code later in the same function. Since it is a translateable message, I do not want to edit it because that would cause unnecessary work of the translators. Especially given that we do not even expect this message to be shown, ever, but we only add this hunk for GCC's benefit. Thank you, Johannes > > > + "Please specify a directory on the command line")); > > + > > /* > > * Strip trailing port number if we've got only a > > * hostname (that is, there is no dir separator but a > > ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 4/4] dir.c: avoid "exceeds maximum object size" error with GCC v12.x 2022-05-24 21:05 ` Johannes Schindelin @ 2022-05-25 13:39 ` Derrick Stolee 2022-05-25 18:27 ` Junio C Hamano 0 siblings, 1 reply; 23+ messages in thread From: Derrick Stolee @ 2022-05-25 13:39 UTC (permalink / raw) To: Johannes Schindelin, Ævar Arnfjörð Bjarmason Cc: Johannes Schindelin via GitGitGadget, git On 5/24/2022 5:05 PM, Johannes Schindelin wrote:> On Tue, 24 May 2022, Ævar Arnfjörð Bjarmason wrote: >> On Tue, May 24 2022, Johannes Schindelin via GitGitGadget wrote: >>> + /* >>> + * It should not be possible to overflow `ptrdiff_t` by passing in an >>> + * insanely long URL, but GCC does not know that and will complain >>> + * without this check. >>> + */ >>> + if (end - start < 0) >>> + die(_("No directory name could be guessed.\n" >> >> This should start with a lower-case letter, see CodingGuidelines. > > This message is copied from existing code later in the same function. > Since it is a translateable message, I do not want to edit it because that > would cause unnecessary work of the translators. Especially given that we > do not even expect this message to be shown, ever, but we only add this > hunk for GCC's benefit. Perhaps this should be a BUG() statement, then? Without any translation? Thanks, -Stolee ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 4/4] dir.c: avoid "exceeds maximum object size" error with GCC v12.x 2022-05-25 13:39 ` Derrick Stolee @ 2022-05-25 18:27 ` Junio C Hamano 0 siblings, 0 replies; 23+ messages in thread From: Junio C Hamano @ 2022-05-25 18:27 UTC (permalink / raw) To: Derrick Stolee Cc: Johannes Schindelin, Ævar Arnfjörð Bjarmason, Johannes Schindelin via GitGitGadget, git Derrick Stolee <derrickstolee@github.com> writes: > On 5/24/2022 5:05 PM, Johannes Schindelin wrote:> On Tue, 24 May 2022, Ævar Arnfjörð Bjarmason wrote: >>> On Tue, May 24 2022, Johannes Schindelin via GitGitGadget wrote: >>>> + /* >>>> + * It should not be possible to overflow `ptrdiff_t` by passing in an >>>> + * insanely long URL, but GCC does not know that and will complain >>>> + * without this check. >>>> + */ >>>> + if (end - start < 0) >>>> + die(_("No directory name could be guessed.\n" >>> >>> This should start with a lower-case letter, see CodingGuidelines. >> >> This message is copied from existing code later in the same function. >> Since it is a translateable message, I do not want to edit it because that >> would cause unnecessary work of the translators. Especially given that we >> do not even expect this message to be shown, ever, but we only add this >> hunk for GCC's benefit. > > Perhaps this should be a BUG() statement, then? Without any > translation? Yeah, both are good. If somehow the caller managed to pass such a long URL then it can be considered a data error at runtime, and not that the user detected a bug in our code, so in that sense die() would be appropriate. It is like xmalloc() running out of memory. On the other hand, the "should not be possible to overflow" in the comment implicitly assumes that it is impossible to pass insanely long URL to trigger the condition from places we think of offhand, like the command line, where the input is limited to a much shorter string. As "we detected a situation that should not happen unless there is a programming or design bug" is what BUG() means, it is also good here---our assumption that this should not be possible turned out to be faulty, so we noticed a design bug. I wonder if we can add a separate macro to add more to the documentation value, though. With something like #define FALSE_WARNING(expression, message) \ do { if (expression) { BUG(message); } while (0) the above would just become FALSE_WARNING(end - start < 0, "ptrdiff_t would not overflow here"); without a need for a big comment before it. We might even be able to optimize it out when building with compilers that do not need the workaround. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 0/4] ci: fix windows-build with GCC v12.x 2022-05-24 0:23 [PATCH 0/4] ci: fix windows-build with GCC v12.x Johannes Schindelin via GitGitGadget ` (3 preceding siblings ...) 2022-05-24 0:23 ` [PATCH 4/4] dir.c: avoid "exceeds maximum object size" error with GCC v12.x Johannes Schindelin via GitGitGadget @ 2022-05-24 15:54 ` Jeff Hostetler 4 siblings, 0 replies; 23+ messages in thread From: Jeff Hostetler @ 2022-05-24 15:54 UTC (permalink / raw) To: Johannes Schindelin via GitGitGadget, git; +Cc: Johannes Schindelin On 5/23/22 8:23 PM, Johannes Schindelin via GitGitGadget wrote: > A recent update of GCC in Git for Windows' SDK (a subset of which is used in > Git's CI/PR builds) broke the build. > > These patches address that, and they are based on maint-2.34 (earlier > maintenance tracks would have a trivial merge conflict due to 013c7e2b070 > (http: drop support for curl < 7.16.0, 2021-07-30) removing support for > USE_CURL_MULTI). > > Johannes Schindelin (4): > compat/win32/syslog: fix use-after-realloc > nedmalloc: avoid new compile error > http.c: avoid danging pointer to local variable `finished` > dir.c: avoid "exceeds maximum object size" error with GCC v12.x > > compat/nedmalloc/nedmalloc.c | 1 - > compat/win32/syslog.c | 2 ++ > dir.c | 9 +++++++++ > http-walker.c | 4 ---- > http.c | 15 +++++++-------- > http.h | 2 +- > 6 files changed, 19 insertions(+), 14 deletions(-) > > > base-commit: 2f0dde7852b7866bb044926f73334ff3fc30654b > Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1238%2Fdscho%2Ffix-win-build-with-gcc-12-v1 > Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1238/dscho/fix-win-build-with-gcc-12-v1 > Pull-Request: https://github.com/gitgitgadget/git/pull/1238 > This looks good to me. I reviewed it earlier in one of our downstream forks. Jeff ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2022-05-25 18:27 UTC | newest] Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-05-24 0:23 [PATCH 0/4] ci: fix windows-build with GCC v12.x Johannes Schindelin via GitGitGadget 2022-05-24 0:23 ` [PATCH 1/4] compat/win32/syslog: fix use-after-realloc Johannes Schindelin via GitGitGadget 2022-05-24 12:39 ` Johannes Schindelin 2022-05-24 20:58 ` Junio C Hamano 2022-05-24 0:23 ` [PATCH 2/4] nedmalloc: avoid new compile error Johannes Schindelin via GitGitGadget 2022-05-24 8:00 ` Ævar Arnfjörð Bjarmason 2022-05-24 15:59 ` René Scharfe 2022-05-24 20:46 ` Johannes Schindelin 2022-05-24 21:33 ` Ævar Arnfjörð Bjarmason 2022-05-24 0:23 ` [PATCH 3/4] http.c: avoid danging pointer to local variable `finished` Johannes Schindelin via GitGitGadget 2022-05-24 7:58 ` Ævar Arnfjörð Bjarmason 2022-05-24 20:06 ` Junio C Hamano 2022-05-24 21:15 ` Johannes Schindelin 2022-05-24 21:45 ` Ævar Arnfjörð Bjarmason 2022-05-24 22:38 ` Junio C Hamano 2022-05-25 10:16 ` Johannes Schindelin 2022-05-25 12:48 ` Ævar Arnfjörð Bjarmason 2022-05-24 0:23 ` [PATCH 4/4] dir.c: avoid "exceeds maximum object size" error with GCC v12.x Johannes Schindelin via GitGitGadget 2022-05-24 5:53 ` Ævar Arnfjörð Bjarmason 2022-05-24 21:05 ` Johannes Schindelin 2022-05-25 13:39 ` Derrick Stolee 2022-05-25 18:27 ` Junio C Hamano 2022-05-24 15:54 ` [PATCH 0/4] ci: fix windows-build " Jeff Hostetler
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).