* [PATCH 0/2] Fix two buffer overflows
@ 2025-04-29 21:47 Zurab Kvachadze
2025-04-29 21:47 ` [PATCH 1/2] expand: Fix negative size parameter to memmove in subevalvar() Zurab Kvachadze
2025-04-29 21:47 ` [PATCH 2/2] expand: pmatch(): Fix buffer overread caused by passing array of chars as string Zurab Kvachadze
0 siblings, 2 replies; 6+ messages in thread
From: Zurab Kvachadze @ 2025-04-29 21:47 UTC (permalink / raw)
To: dash; +Cc: Zurab Kvachadze
This little patch series fixes two memory bugs in dash. One was reported by Kate
Deplaix and the second one was accidentally found upon testing a potential fix.
Zurab Kvachadze (2):
expand: Fix negative size parameter to memmove in subevalvar()
expand: pmatch(): Fix buffer overread caused by passing array of chars
as string
src/expand.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
--
2.45.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 1/2] expand: Fix negative size parameter to memmove in subevalvar() 2025-04-29 21:47 [PATCH 0/2] Fix two buffer overflows Zurab Kvachadze @ 2025-04-29 21:47 ` Zurab Kvachadze 2025-05-02 5:34 ` Herbert Xu 2025-04-29 21:47 ` [PATCH 2/2] expand: pmatch(): Fix buffer overread caused by passing array of chars as string Zurab Kvachadze 1 sibling, 1 reply; 6+ messages in thread From: Zurab Kvachadze @ 2025-04-29 21:47 UTC (permalink / raw) To: dash; +Cc: Zurab Kvachadze A bug was reported on the mailing list that causes dash to segfault on the following cmdline: dash -c 'echo test > "${1%.in}"' sh /tmp/META.in This is caused by a memory corruption resulting from a bug in scanright(). The function returns a pointer to string A, but later in subevalvar() that pointer is subtracted from the base of string B (which address is less than the address of A's substring). This produces a negative integer which is later happily passed as a parameter to memmove. The correct behaviour for the function is to return a pointer to a substring of string B. This erroneous behaviour is caused by the fact that under certain conditions (FNMATCH_IS_ENABLED being undefined) scanright() iterates over the pattern string (that the string A in the example above - startp in the function), when it is meant to iterate over the string with removed escapes (string B - rmesc in the function). Due to the fact that if FNMATCH_IS_ENABLED is undefined, each for loop iteration sets loc2 (initially pointing to str. B's end - rmescend) to loc (initially pointing to str. A's end - endp), which is not the desired behaviour. This commit slightly changes the for loop header to make its behaviour correct for any value of FNMATCH_IS_ENABLED, thus fixing the root issue. Fixes: https://lore.kernel.org/dash/CWLP265MB4157446AD56C013BB88575CFBCA82@CWLP265MB4157.GBRP265.PROD.OUTLOOK.COM/ Reported-by: Kate Deplaix Signed-off-by: Zurab Kvachadze <zurabid2016@gmail.com> --- src/expand.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/expand.c b/src/expand.c index d73f29c..171c135 100644 --- a/src/expand.c +++ b/src/expand.c @@ -645,8 +645,7 @@ static char *scanright(char *startp, char *endp, char *rmesc, char *rmescend, char *loc; char *loc2; - for (loc = endp, loc2 = rmescend;; - FNMATCH_IS_ENABLED ? loc2-- : (loc2 = loc)) { + for (loc = endp, loc2 = rmescend;; loc--, loc2--) { char *s = FNMATCH_IS_ENABLED ? loc2 : loc; char c = *s; unsigned ml; @@ -660,7 +659,7 @@ static char *scanright(char *startp, char *endp, char *rmesc, char *rmescend, *(FNMATCH_IS_ENABLED ? loc2 : loc) = c; if (match) return FNMATCH_IS_ENABLED && quotes ? loc : loc2; - if (--loc < startp) + if (loc == startp || loc2 == rmesc) break; if (!esc--) esc = esclen(startp, loc); -- 2.45.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] expand: Fix negative size parameter to memmove in subevalvar() 2025-04-29 21:47 ` [PATCH 1/2] expand: Fix negative size parameter to memmove in subevalvar() Zurab Kvachadze @ 2025-05-02 5:34 ` Herbert Xu 2025-05-02 5:45 ` Herbert Xu 0 siblings, 1 reply; 6+ messages in thread From: Herbert Xu @ 2025-05-02 5:34 UTC (permalink / raw) To: Zurab Kvachadze; +Cc: dash, zurabid2016 Zurab Kvachadze <zurabid2016@gmail.com> wrote: > A bug was reported on the mailing list that causes dash to segfault on > the following cmdline: > > dash -c 'echo test > "${1%.in}"' sh /tmp/META.in > > This is caused by a memory corruption resulting from a bug in > scanright(). The function returns a pointer to string A, but later in > subevalvar() that pointer is subtracted from the base of string B (which > address is less than the address of A's substring). This produces a > negative integer which is later happily passed as a parameter to > memmove. The correct behaviour for the function is to return a pointer > to a substring of string B. > > This erroneous behaviour is caused by the fact that under certain > conditions (FNMATCH_IS_ENABLED being undefined) scanright() iterates > over the pattern string (that the string A in the example above - startp > in the function), when it is meant to iterate over the string with > removed escapes (string B - rmesc in the function). > > Due to the fact that if FNMATCH_IS_ENABLED is undefined, each for loop > iteration sets loc2 (initially pointing to str. B's end - rmescend) to > loc (initially pointing to str. A's end - endp), which is not the > desired behaviour. > > This commit slightly changes the for loop header to make its behaviour > correct for any value of FNMATCH_IS_ENABLED, thus fixing the root issue. > > Fixes: https://lore.kernel.org/dash/CWLP265MB4157446AD56C013BB88575CFBCA82@CWLP265MB4157.GBRP265.PROD.OUTLOOK.COM/ > Reported-by: Kate Deplaix > Signed-off-by: Zurab Kvachadze <zurabid2016@gmail.com> > --- > src/expand.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) Thanks, but I think this is already fixed by: https://patchwork.kernel.org/project/dash/patch/Z81WqTBtj9TRqQzy@gondor.apana.org.au/ Cheers, -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] expand: Fix negative size parameter to memmove in subevalvar() 2025-05-02 5:34 ` Herbert Xu @ 2025-05-02 5:45 ` Herbert Xu 0 siblings, 0 replies; 6+ messages in thread From: Herbert Xu @ 2025-05-02 5:45 UTC (permalink / raw) To: Zurab Kvachadze; +Cc: dash On Fri, May 02, 2025 at 01:34:17PM +0800, Herbert Xu wrote: > > Thanks, but I think this is already fixed by: > > https://patchwork.kernel.org/project/dash/patch/Z81WqTBtj9TRqQzy@gondor.apana.org.au/ Actually I think it's https://git.kernel.org/pub/scm/utils/dash/dash.git/commit/?id=a76c0f428e64d6ccc37c066ed4d47f49b52f9ae7 which I forgot to push out. It's out there now. Thanks, -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] expand: pmatch(): Fix buffer overread caused by passing array of chars as string 2025-04-29 21:47 [PATCH 0/2] Fix two buffer overflows Zurab Kvachadze 2025-04-29 21:47 ` [PATCH 1/2] expand: Fix negative size parameter to memmove in subevalvar() Zurab Kvachadze @ 2025-04-29 21:47 ` Zurab Kvachadze 2025-05-03 7:23 ` Herbert Xu 1 sibling, 1 reply; 6+ messages in thread From: Zurab Kvachadze @ 2025-04-29 21:47 UTC (permalink / raw) To: dash; +Cc: Zurab Kvachadze strpbrk() accepts two null-terminated string arguments. stop[] is char array that is not null-terminated but is still passed as a second argument to strpbrk. This causes buffer overread, which is detected by AddressSanitizer. This commit adds an explicit null-terminated to the end of the array. Signed-off-by: Zurab Kvachadze <zurabid2016@gmail.com> --- src/expand.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/expand.c b/src/expand.c index 171c135..8cff60d 100644 --- a/src/expand.c +++ b/src/expand.c @@ -1890,7 +1890,9 @@ static __attribute__((noinline)) int ccmatch(char *p, const char *mbc, int ml, static int pmatch(char *pattern, const char *string) { - char stop[] = { 0, CTLESC, CTLMBCHAR }; + /* stop should be null-terminated as it passed as a string to + * strpbrk. */ + char stop[] = { 0, CTLESC, CTLMBCHAR, '\0' }; const char *q; unsigned mb; char *p; -- 2.45.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] expand: pmatch(): Fix buffer overread caused by passing array of chars as string 2025-04-29 21:47 ` [PATCH 2/2] expand: pmatch(): Fix buffer overread caused by passing array of chars as string Zurab Kvachadze @ 2025-05-03 7:23 ` Herbert Xu 0 siblings, 0 replies; 6+ messages in thread From: Herbert Xu @ 2025-05-03 7:23 UTC (permalink / raw) To: Zurab Kvachadze; +Cc: dash, zurabid2016 Zurab Kvachadze <zurabid2016@gmail.com> wrote: > strpbrk() accepts two null-terminated string arguments. stop[] is char > array that is not null-terminated but is still passed as a second > argument to strpbrk. This causes buffer overread, which is detected by > AddressSanitizer. > > This commit adds an explicit null-terminated to the end of the array. > > Signed-off-by: Zurab Kvachadze <zurabid2016@gmail.com> > --- > src/expand.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) Patch applied. Thanks. -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-05-03 7:23 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-04-29 21:47 [PATCH 0/2] Fix two buffer overflows Zurab Kvachadze 2025-04-29 21:47 ` [PATCH 1/2] expand: Fix negative size parameter to memmove in subevalvar() Zurab Kvachadze 2025-05-02 5:34 ` Herbert Xu 2025-05-02 5:45 ` Herbert Xu 2025-04-29 21:47 ` [PATCH 2/2] expand: pmatch(): Fix buffer overread caused by passing array of chars as string Zurab Kvachadze 2025-05-03 7:23 ` Herbert Xu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox