[PATCH] parser: Skip parsing of old-style command substitution here-doc marker
Herbert Xu <[email protected]> Sat, 13 Sep 2025 17:59:28 +0800
| Newsgroups | org.kernel.vger.dash |
|---|---|
| Message-ID | <[email protected]> |
On Fri, Aug 29, 2025 at 07:40:16PM -0700, Nathan Mills wrote: > > * Crash #0 is a null-pointer-dereference. I haven't found the fix yet > but it is probably simple. > > redir->nhere.doc is NULL. The global variable **heredoclist** is also > NULL and parseheredoc does nothing when heredoclist is NULL. > > 1. readtoken1 > 2. parseheredoc (heredoclist equals heredoc which is the same as the > value in the next step) > 3. parseheredoc (heredoclist is NULL, heredoc is 0x5555560bb6a8 <stackbase+232>) > 4. parsefname > 5. parseheredoc (heredoclist->here->nhere.doc->narg.text equals the > empty string) > 6. **SIGSEGV** openhere (redir->nhere.doc is **NULL**) > > ** Crash #0: null pointer dereference ** > > Base64'd > > dmVzjHdyPDwAAACAYAAAAHd3cjw8AAAAgGAAAACA/38zZGlsaQ== > > Minimized: > > src/dash -c $(echo -c "<<\`<<\0\`") This is caused by the unnecessary recursive parsing of old-style command substitution which then gets confused by the embedded here-document. Fix this by skipping the recursive parsing of command substitution if it is old-style and a here-document marker. Reported-by: Nathan Mills <[email protected]> Fixes: 7a11b3e330a3 ("parser: Extend coverage of CHKEOFMARK") Signed-off-by: Herbert Xu <[email protected]> diff --git a/src/parser.c b/src/parser.c index a3b004b..975cf89 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1510,7 +1510,6 @@ parsebackq: { int uninitialized_var(saveprompt); struct heredoc *saveheredoclist; struct nodelist **nlpp; - size_t psavelen; size_t savelen; union node *n; unsigned ml; @@ -1521,24 +1520,28 @@ parsebackq: { STADJUST(oldstyle - 1, out); out[-1] = CTLBACKQ; } - str = stackblock(); - savelen = out - (char *)stackblock(); - grabstackblock(savelen); + if (!chkeofmark || !oldstyle) { + str = stackblock(); + savelen = out - (char *)stackblock(); + grabstackblock(savelen); + STARTSTACKSTR(out); + } if (oldstyle) { /* We must read until the closing backquote, giving special treatment to some slashes, and then push the string and reread it as input, interpreting it normally. */ - char *pout; + bool done = false; + char *pout = out; int pc; - STARTSTACKSTR(pout); - for (;;) { + while (!done) { if (needprompt) { setprompt(2); } switch (pc = pgetc_eatbnl()) { case '`': - goto done; + done = true; + break; case '\\': pc = pgetc(); @@ -1564,9 +1567,11 @@ parsebackq: { } STPUTC(pc, pout); } -done: - STPUTC('\0', pout); - psavelen = pout - (char *)stackblock(); + if (chkeofmark) { + out = pout; + goto parsebackq_oldreturn; + } + pout[-1] = 0; pstr = grabstackstr(pout); setinputstring(pstr); } @@ -1608,10 +1613,6 @@ done: * parsing. */ tokpushback = 0; - if (chkeofmark) { - pstr[psavelen - 1] = '`'; - out = stnputs(pstr, psavelen, out); - } goto parsebackq_oldreturn; } else { if (chkeofmark) { -- Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt