aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2018-06-27 23:44:37 +0000
committerWarner Losh <imp@FreeBSD.org>2018-06-27 23:44:37 +0000
commit54aa4076257f72b962d71b447bcd028de2b43a66 (patch)
treeaa4821ffd96ed0785a923a69d8245a537e13b6d1 /sbin
parent37e29448ea19a6e2d7933e9f876d5f1e962dcf75 (diff)
downloadsrc-54aa4076257f72b962d71b447bcd028de2b43a66.tar.gz
src-54aa4076257f72b962d71b447bcd028de2b43a66.zip
Safely quote all variable expansions.
When expanding a variable set by a message from the kernel, safely quote all arguments expanded when creating a command line for the shell. Reviewd by: Shawn Webb, Oliver Pinter, brd@ Sponsored by: Netflix
Notes
Notes: svn path=/head/; revision=335753
Diffstat (limited to 'sbin')
-rw-r--r--sbin/devd/devd.cc29
-rw-r--r--sbin/devd/devd.hh1
2 files changed, 27 insertions, 3 deletions
diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc
index f57f41eaa7ea..bb7195cafee6 100644
--- a/sbin/devd/devd.cc
+++ b/sbin/devd/devd.cc
@@ -636,6 +636,30 @@ config::is_id_char(char ch) const
ch == '-'));
}
+string
+config::shell_quote(const string &s)
+{
+ string buffer;
+
+ /*
+ * Enclose the string in $' ' with escapes for ' and / characters making
+ * it one argument and ensuring the shell won't be affected by its
+ * usual list of candidates.
+ */
+ buffer.reserve(s.length() * 3 / 2);
+ buffer += '$';
+ buffer += '\'';
+ for (const char &c : s) {
+ if (c == '\'' || c == '\\') {
+ buffer += '\\';
+ }
+ buffer += c;
+ }
+ buffer += '\'';
+
+ return buffer;
+}
+
void
config::expand_one(const char *&src, string &dst)
{
@@ -650,8 +674,7 @@ config::expand_one(const char *&src, string &dst)
}
// $(foo) -> $(foo)
- // Not sure if I want to support this or not, so for now we just pass
- // it through.
+ // This is the escape hatch for passing down shell subcommands
if (*src == '(') {
dst += '$';
count = 1;
@@ -677,7 +700,7 @@ config::expand_one(const char *&src, string &dst)
do {
buffer += *src++;
} while (is_id_char(*src));
- dst.append(get_variable(buffer));
+ dst.append(shell_quote(get_variable(buffer)));
}
const string
diff --git a/sbin/devd/devd.hh b/sbin/devd/devd.hh
index af4ce192dec0..534c4d4c5a9d 100644
--- a/sbin/devd/devd.hh
+++ b/sbin/devd/devd.hh
@@ -173,6 +173,7 @@ protected:
void parse_one_file(const char *fn);
void parse_files_in_dir(const char *dirname);
void expand_one(const char *&src, std::string &dst);
+ std::string shell_quote(const std::string &s);
bool is_id_char(char) const;
bool chop_var(char *&buffer, char *&lhs, char *&rhs) const;
private: