Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jun 2018 23:44:37 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r335753 - head/sbin/devd
Message-ID:  <201806272344.w5RNibEr085247@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Wed Jun 27 23:44:37 2018
New Revision: 335753
URL: https://svnweb.freebsd.org/changeset/base/335753

Log:
  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

Modified:
  head/sbin/devd/devd.cc
  head/sbin/devd/devd.hh

Modified: head/sbin/devd/devd.cc
==============================================================================
--- head/sbin/devd/devd.cc	Wed Jun 27 23:02:18 2018	(r335752)
+++ head/sbin/devd/devd.cc	Wed Jun 27 23:44:37 2018	(r335753)
@@ -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

Modified: head/sbin/devd/devd.hh
==============================================================================
--- head/sbin/devd/devd.hh	Wed Jun 27 23:02:18 2018	(r335752)
+++ head/sbin/devd/devd.hh	Wed Jun 27 23:44:37 2018	(r335753)
@@ -173,6 +173,7 @@ class config (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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201806272344.w5RNibEr085247>