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:
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to