aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-07-25 11:07:52 -0400
committerLibravatar GitHub <noreply@github.com>2016-07-25 11:07:52 -0400
commit20b89731df5868f1fb66ab93dcb6b7ec4dc2864b (patch)
treeca8eebc09d3273ad60a5e4332bc52abc385242cb
parent0.9.42~rc2 development (diff)
parentFix problem with single quotes in args (diff)
downloadfirejail-20b89731df5868f1fb66ab93dcb6b7ec4dc2864b.tar.gz
firejail-20b89731df5868f1fb66ab93dcb6b7ec4dc2864b.tar.zst
firejail-20b89731df5868f1fb66ab93dcb6b7ec4dc2864b.zip
Merge pull request #629 from manevich/patch-2
Additional fixes of command line quoting
-rw-r--r--src/firejail/main.c92
-rw-r--r--src/firejail/run_symlink.c11
2 files changed, 82 insertions, 21 deletions
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 25063700c..cbc3d57cf 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -2008,8 +2008,35 @@ int main(int argc, char **argv) {
2008 int i; 2008 int i;
2009 int len = 0; 2009 int len = 0;
2010 int argcnt = argc - prog_index; 2010 int argcnt = argc - prog_index;
2011 for (i = 0; i < argcnt; i++) 2011 int j;
2012 len += strlen(argv[i + prog_index]) + 3; // + ' ' + 2 '"' 2012 bool in_quotes = false;
2013
2014 for (i = 0; i < argcnt; i++) {
2015 in_quotes = false;
2016 for (j = 0; j < strlen(argv[i + prog_index]); j++) {
2017 if (argv[i + prog_index][j] == '\'') {
2018 if (in_quotes)
2019 len++;
2020 if (j > 0 && argv[i + prog_index][j-1] == '\'')
2021 len++;
2022 else
2023 len += 3;
2024 in_quotes = false;
2025 } else {
2026 if (!in_quotes)
2027 len++;
2028 len++;
2029 in_quotes = true;
2030 }
2031 }
2032 if (in_quotes) {
2033 len++;
2034 }
2035 if (strlen(argv[i + prog_index]) == 0) {
2036 len += 2;
2037 }
2038 len++;
2039 }
2013 2040
2014 // build the string 2041 // build the string
2015 cfg.command_line = malloc(len + 1); // + '\0' 2042 cfg.command_line = malloc(len + 1); // + '\0'
@@ -2022,21 +2049,64 @@ int main(int argc, char **argv) {
2022 char *ptr1 = cfg.command_line; 2049 char *ptr1 = cfg.command_line;
2023 char *ptr2 = cfg.window_title; 2050 char *ptr2 = cfg.window_title;
2024 for (i = 0; i < argcnt; i++) { 2051 for (i = 0; i < argcnt; i++) {
2025 // detect bash commands 2052
2026 if (strstr(argv[i + prog_index], "&&") || strstr(argv[i + prog_index], "||")) { 2053 // enclose args by single quotes,
2027 sprintf(ptr1, "%s ", argv[i + prog_index]); 2054 // and since single quote can't be represented in single quoted text
2055 // each occurence of it should be enclosed by double quotes
2056 in_quotes = false;
2057 for (j = 0; j < strlen(argv[i + prog_index]); j++) {
2058 // single quote
2059 if (argv[i + prog_index][j] == '\'') {
2060 if (in_quotes) {
2061 // close quotes
2062 ptr1[0] = '\'';
2063 ptr1++;
2064 }
2065 // previous char was single quote too
2066 if (j > 0 && argv[i + prog_index][j-1] == '\'') {
2067 ptr1--;
2068 sprintf(ptr1, "\'\"");
2069 }
2070 // this first in series
2071 else
2072 {
2073 sprintf(ptr1, "\"\'\"");
2074 }
2075 ptr1 += strlen(ptr1);
2076 in_quotes = false;
2077 }
2078 // anything other
2079 else
2080 {
2081 if (!in_quotes) {
2082 // open quotes
2083 ptr1[0] = '\'';
2084 ptr1++;
2085 }
2086 ptr1[0] = argv[i + prog_index][j];
2087 ptr1++;
2088 in_quotes = true;
2089 }
2028 } 2090 }
2029 else if (arg_command){ 2091 // close quotes
2030 sprintf(ptr1, "%s ", argv[i + prog_index]); 2092 if (in_quotes) {
2093 ptr1[0] = '\'';
2094 ptr1++;
2031 } 2095 }
2032 else { 2096 // handle empty argument case
2033 sprintf(ptr1, "\'%s\' ", argv[i + prog_index]); 2097 if (strlen(argv[i + prog_index]) == 0) {
2098 sprintf(ptr1, "\'\'");
2099 ptr1 += strlen(ptr1);
2034 } 2100 }
2035 sprintf(ptr2, "%s ", argv[i + prog_index]); 2101 // add space
2036 2102 sprintf(ptr1, " ");
2037 ptr1 += strlen(ptr1); 2103 ptr1 += strlen(ptr1);
2104
2105 sprintf(ptr2, "%s ", argv[i + prog_index]);
2038 ptr2 += strlen(ptr2); 2106 ptr2 += strlen(ptr2);
2039 } 2107 }
2108
2109 assert(len == strlen(cfg.command_line));
2040 } 2110 }
2041 2111
2042 assert(cfg.command_name); 2112 assert(cfg.command_name);
diff --git a/src/firejail/run_symlink.c b/src/firejail/run_symlink.c
index 26c6c5133..020e70b80 100644
--- a/src/firejail/run_symlink.c
+++ b/src/firejail/run_symlink.c
@@ -103,16 +103,7 @@ void run_symlink(int argc, char **argv) {
103 a[1] = program; 103 a[1] = program;
104 int i; 104 int i;
105 for (i = 0; i < (argc - 1); i++) { 105 for (i = 0; i < (argc - 1); i++) {
106 // look for & character 106 a[i + 2] = argv[i + 1];
107 if (strchr(argv[i + 1], '&')) {
108 char *str = malloc(strlen(argv[i + 1]));
109 if (str == NULL)
110 errExit("malloc");
111 sprintf(str, "\"%s\"", argv[i + 1]);
112 a[i + 2] = str;
113 }
114 else
115 a[i + 2] = argv[i + 1];
116 } 107 }
117 a[i + 2] = NULL; 108 a[i + 2] = NULL;
118 execvp(a[0], a); 109 execvp(a[0], a);