Dash Archive mirror
 help / color / mirror / Atom feed
From: Matt Whitlock <dash@mattwhitlock.name>
To: dash@vger.kernel.org
Subject: Bug in Dash's unquoting of backslashes within backquoted strings
Date: Thu, 21 May 2020 16:06:38 -0400	[thread overview]
Message-ID: <b2fe3536-23b8-4d04-8197-701ab50da86f@mattwhitlock.name> (raw)

A minimal example:

: `: "\\\\
\\$(bug)"`

That's one command, containing a newline character, embedded in a 
double-quoted string, embedded in a backquoted string. The command is an 
invocation of the : (colon) built-in, passing arguments obtained by word 
splitting the result of the backquoted command substitution.

The Open Group says: "Within the backquoted style of command substitution, 
backslash shall retain its literal meaning, except when followed by: '$', 
'`', or '\' (dollar sign, backquote, backslash)." Thus, each pair of 
backslashes between the backquotes is to be reduced to a single backslash.

Thus, the subcommand to be executed is:

: "\\
\$(bug)"

This subcommand is an invocation of the : (colon) built-in command, passing 
a single argument obtained by performing quote removal on the double-quoted 
string. After quote removal, the resulting argument consists of these eight 
characters: backslash, newline, dollar sign, open parenthesis, b, u, g, 
close parenthesis.

If the above subcommand is entered directly at the Dash command line, all 
is well. However, when it appears inside a backquoted subcommand (with the 
backslash characters being appropriately escaped), such as given at the top 
of this report, then Dash processes it incorrectly:

/bin/sh: 1: bug: not found

Dash apparently skips over the backslash immediately following the newline 
embedded in the double-quoted string. Thus, Dash sees the dollar sign as 
introducing a command substitution rather than as a literal character.

This does not happen if the backslashes preceding the embedded newline are 
absent. It also does not happen if any other character, including linear 
whitespace, is inserted immediately after the embedded newline.

Both Bash and Busybox Ash get it right. Dash is non-conformant.

This bug has potentially grave security implications since Dash is 
interpreting a string literal as though it were a command and executing it. 
If the word "bug" in my examples above had been "rm -rf /" instead, the 
results would have been catastrophic.

             reply	other threads:[~2020-05-21 20:09 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-21 20:06 Matt Whitlock [this message]
2020-05-21 21:38 ` Bug in Dash's unquoting of backslashes within backquoted strings Ron Yorston
2020-05-21 21:57   ` Ron Yorston
2020-05-26 13:19     ` parser: Fix double-backslash nl in old-style command sub Herbert Xu
2020-05-21 22:02   ` Bug in Dash's unquoting of backslashes within backquoted strings Harald van Dijk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b2fe3536-23b8-4d04-8197-701ab50da86f@mattwhitlock.name \
    --to=dash@mattwhitlock.name \
    --cc=dash@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).