diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/main.c | 29 | ||||
-rw-r--r-- | src/firejail/no_sandbox.c | 2 | ||||
-rw-r--r-- | src/firejail/profile.c | 27 | ||||
-rw-r--r-- | src/firejail/util.c | 39 | ||||
-rw-r--r-- | src/man/firejail.txt | 24 |
5 files changed, 79 insertions, 42 deletions
diff --git a/src/firejail/main.c b/src/firejail/main.c index 1835d8de2..070eb47f3 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -2187,34 +2187,21 @@ int main(int argc, char **argv, char **envp) { | |||
2187 | else if (strncmp(argv[i], "--name=", 7) == 0) { | 2187 | else if (strncmp(argv[i], "--name=", 7) == 0) { |
2188 | cfg.name = argv[i] + 7; | 2188 | cfg.name = argv[i] + 7; |
2189 | if (strlen(cfg.name) == 0) { | 2189 | if (strlen(cfg.name) == 0) { |
2190 | fprintf(stderr, "Error: please provide a name for sandbox\n"); | 2190 | fprintf(stderr, "Error: invalid sandbox name: cannot be empty\n"); |
2191 | return 1; | 2191 | return 1; |
2192 | } | 2192 | } |
2193 | if (invalid_name(cfg.name) || has_cntrl_chars(cfg.name)) { | 2193 | if (invalid_name(cfg.name)) { |
2194 | fprintf(stderr, "Error: invalid sandbox name\n"); | 2194 | fprintf(stderr, "Error: invalid sandbox name\n"); |
2195 | return 1; | 2195 | return 1; |
2196 | } | 2196 | } |
2197 | } | 2197 | } |
2198 | else if (strncmp(argv[i], "--hostname=", 11) == 0) { | 2198 | else if (strncmp(argv[i], "--hostname=", 11) == 0) { |
2199 | cfg.hostname = argv[i] + 11; | 2199 | cfg.hostname = argv[i] + 11; |
2200 | size_t len = strlen(cfg.hostname); | 2200 | if (strlen(cfg.hostname) == 0) { |
2201 | if (len == 0 || len > 253) { | 2201 | fprintf(stderr, "Error: invalid hostname: cannot be empty\n"); |
2202 | fprintf(stderr, "Error: please provide a valid hostname for sandbox, with maximum length of 253 ASCII characters\n"); | ||
2203 | return 1; | 2202 | return 1; |
2204 | } | 2203 | } |
2205 | int invalid = invalid_name(cfg.hostname); | 2204 | if (invalid_name(cfg.hostname)) { |
2206 | char* hostname = cfg.hostname; | ||
2207 | while (*hostname && !invalid) { | ||
2208 | invalid = invalid || !( | ||
2209 | (*hostname >= 'a' && *hostname <= 'z') || | ||
2210 | (*hostname >= 'A' && *hostname <= 'Z') || | ||
2211 | (*hostname >= '0' && *hostname <= '9') || | ||
2212 | (*hostname == '-' || *hostname == '.')); | ||
2213 | hostname++; | ||
2214 | } | ||
2215 | invalid = invalid || cfg.hostname[0] == '-'; // must not start with - | ||
2216 | invalid = invalid || cfg.hostname[len - 1] == '-'; // must not end with - | ||
2217 | if (invalid) { | ||
2218 | fprintf(stderr, "Error: invalid hostname\n"); | 2205 | fprintf(stderr, "Error: invalid hostname\n"); |
2219 | return 1; | 2206 | return 1; |
2220 | } | 2207 | } |
@@ -2847,7 +2834,11 @@ int main(int argc, char **argv, char **envp) { | |||
2847 | // set sandbox name and start normally | 2834 | // set sandbox name and start normally |
2848 | cfg.name = argv[i] + 16; | 2835 | cfg.name = argv[i] + 16; |
2849 | if (strlen(cfg.name) == 0) { | 2836 | if (strlen(cfg.name) == 0) { |
2850 | fprintf(stderr, "Error: please provide a name for sandbox\n"); | 2837 | fprintf(stderr, "Error: invalid sandbox name: cannot be empty\n"); |
2838 | return 1; | ||
2839 | } | ||
2840 | if (invalid_name(cfg.name)) { | ||
2841 | fprintf(stderr, "Error: invalid sandbox name\n"); | ||
2851 | return 1; | 2842 | return 1; |
2852 | } | 2843 | } |
2853 | } | 2844 | } |
diff --git a/src/firejail/no_sandbox.c b/src/firejail/no_sandbox.c index 22ee9dc3c..9c5e3ee58 100644 --- a/src/firejail/no_sandbox.c +++ b/src/firejail/no_sandbox.c | |||
@@ -120,7 +120,7 @@ int check_kernel_procs(void) { | |||
120 | 120 | ||
121 | // read file | 121 | // read file |
122 | char buf[100]; | 122 | char buf[100]; |
123 | if (fgets(buf, 10, fp) == NULL) { | 123 | if (fgets(buf, 100, fp) == NULL) { |
124 | fwarning("cannot read %s\n", fname); | 124 | fwarning("cannot read %s\n", fname); |
125 | fclose(fp); | 125 | fclose(fp); |
126 | free(fname); | 126 | free(fname); |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 202bcf4da..ae881664b 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -326,22 +326,13 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
326 | } | 326 | } |
327 | // sandbox name | 327 | // sandbox name |
328 | else if (strncmp(ptr, "name ", 5) == 0) { | 328 | else if (strncmp(ptr, "name ", 5) == 0) { |
329 | int only_numbers = 1; | ||
330 | cfg.name = ptr + 5; | 329 | cfg.name = ptr + 5; |
331 | if (strlen(cfg.name) == 0) { | 330 | if (strlen(cfg.name) == 0) { |
332 | fprintf(stderr, "Error: invalid sandbox name\n"); | 331 | fprintf(stderr, "Error: invalid sandbox name: cannot be empty\n"); |
333 | exit(1); | 332 | exit(1); |
334 | } | 333 | } |
335 | const char *c = cfg.name; | 334 | if (invalid_name(cfg.name)) { |
336 | while (*c) { | 335 | fprintf(stderr, "Error: invalid sandbox name\n"); |
337 | if (!isdigit(*c)) { | ||
338 | only_numbers = 0; | ||
339 | break; | ||
340 | } | ||
341 | ++c; | ||
342 | } | ||
343 | if (only_numbers) { | ||
344 | fprintf(stderr, "Error: invalid sandbox name: it only contains digits\n"); | ||
345 | exit(1); | 336 | exit(1); |
346 | } | 337 | } |
347 | return 0; | 338 | return 0; |
@@ -1165,6 +1156,14 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
1165 | // hostname | 1156 | // hostname |
1166 | if (strncmp(ptr, "hostname ", 9) == 0) { | 1157 | if (strncmp(ptr, "hostname ", 9) == 0) { |
1167 | cfg.hostname = ptr + 9; | 1158 | cfg.hostname = ptr + 9; |
1159 | if (strlen(cfg.hostname) == 0) { | ||
1160 | fprintf(stderr, "Error: invalid hostname: cannot be empty\n"); | ||
1161 | exit(1); | ||
1162 | } | ||
1163 | if (invalid_name(cfg.hostname)) { | ||
1164 | fprintf(stderr, "Error: invalid hostname\n"); | ||
1165 | exit(1); | ||
1166 | } | ||
1168 | return 0; | 1167 | return 0; |
1169 | } | 1168 | } |
1170 | 1169 | ||
@@ -1647,6 +1646,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
1647 | // set sandbox name and start normally | 1646 | // set sandbox name and start normally |
1648 | cfg.name = ptr + 14; | 1647 | cfg.name = ptr + 14; |
1649 | if (strlen(cfg.name) == 0) { | 1648 | if (strlen(cfg.name) == 0) { |
1649 | fprintf(stderr, "Error: invalid sandbox name: cannot be empty\n"); | ||
1650 | exit(1); | ||
1651 | } | ||
1652 | if (invalid_name(cfg.name)) { | ||
1650 | fprintf(stderr, "Error: invalid sandbox name\n"); | 1653 | fprintf(stderr, "Error: invalid sandbox name\n"); |
1651 | exit(1); | 1654 | exit(1); |
1652 | } | 1655 | } |
diff --git a/src/firejail/util.c b/src/firejail/util.c index a0af3d4bf..555486916 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -1476,23 +1476,46 @@ int ascii_isxdigit(unsigned char c) { | |||
1476 | return ret; | 1476 | return ret; |
1477 | } | 1477 | } |
1478 | 1478 | ||
1479 | // allow strict ASCII letters and numbers; names with only numbers are rejected; spaces are rejected | 1479 | // Note: Keep this in sync with NAME VALIDATION in src/man/firejail.txt. |
1480 | // | ||
1481 | // Allow only ASCII letters, digits and a few special characters; names with | ||
1482 | // only numbers are rejected; spaces and control characters are rejected. | ||
1480 | int invalid_name(const char *name) { | 1483 | int invalid_name(const char *name) { |
1481 | const char *c = name; | 1484 | const char *c = name; |
1482 | |||
1483 | int only_numbers = 1; | 1485 | int only_numbers = 1; |
1486 | |||
1487 | if (strlen(name) > 253) | ||
1488 | return 1; | ||
1489 | |||
1490 | // must start with alnum | ||
1491 | if (!ascii_isalnum(*c)) | ||
1492 | return 1; | ||
1493 | if (!ascii_isdigit(*c)) | ||
1494 | only_numbers = 0; | ||
1495 | ++c; | ||
1496 | |||
1484 | while (*c) { | 1497 | while (*c) { |
1485 | if (!ascii_isalnum(*c)) | 1498 | switch (*c) { |
1486 | return 1; | 1499 | case '-': |
1487 | if (!ascii_isdigit(*c)) | 1500 | case '.': |
1501 | case '_': | ||
1488 | only_numbers = 0; | 1502 | only_numbers = 0; |
1503 | break; | ||
1504 | default: | ||
1505 | if (!ascii_isalnum(*c)) | ||
1506 | return 1; | ||
1507 | if (!ascii_isdigit(*c)) | ||
1508 | only_numbers = 0; | ||
1509 | } | ||
1489 | ++c; | 1510 | ++c; |
1490 | } | 1511 | } |
1491 | if (only_numbers) | 1512 | |
1513 | // must end with alnum | ||
1514 | --c; | ||
1515 | if (!ascii_isalnum(*c)) | ||
1492 | return 1; | 1516 | return 1; |
1493 | 1517 | ||
1494 | // restrict name to 64 chars max | 1518 | if (only_numbers) |
1495 | if (strlen(name) > 64) | ||
1496 | return 1; | 1519 | return 1; |
1497 | 1520 | ||
1498 | return 0; | 1521 | return 0; |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 586ef9852..19fc94ebd 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -876,6 +876,8 @@ Print options end exit. | |||
876 | \fB\-\-hostname=name | 876 | \fB\-\-hostname=name |
877 | Set sandbox hostname. | 877 | Set sandbox hostname. |
878 | .br | 878 | .br |
879 | For valid names, see the \fBNAME VALIDATION\fR section. | ||
880 | .br | ||
879 | 881 | ||
880 | .br | 882 | .br |
881 | Example: | 883 | Example: |
@@ -1180,7 +1182,9 @@ Switching to pid 1932, the first child process inside the sandbox | |||
1180 | .TP | 1182 | .TP |
1181 | \fB\-\-join-or-start=name | 1183 | \fB\-\-join-or-start=name |
1182 | Join the sandbox identified by name or start a new one. | 1184 | Join the sandbox identified by name or start a new one. |
1183 | Same as "firejail --join=name" if sandbox with specified name exists, otherwise same as "firejail --name=name ..." | 1185 | Same as "firejail --join=name" if sandbox with specified name exists, otherwise |
1186 | same as "firejail --name=name ...". | ||
1187 | See \fB\-\-name\fR for details. | ||
1184 | .br | 1188 | .br |
1185 | Note that in contrary to other join options there is respective profile option. | 1189 | Note that in contrary to other join options there is respective profile option. |
1186 | 1190 | ||
@@ -1340,8 +1344,13 @@ $ firejail \-\-net=eth0 \-\-mtu=1492 | |||
1340 | \fB\-\-name=name | 1344 | \fB\-\-name=name |
1341 | Set sandbox name. Several options, such as \-\-join and \-\-shutdown, can use | 1345 | Set sandbox name. Several options, such as \-\-join and \-\-shutdown, can use |
1342 | this name to identify a sandbox. | 1346 | this name to identify a sandbox. |
1343 | The name cannot contain only digits, as that is treated as a PID in the other options, such as in \-\-join. | 1347 | The name cannot contain only digits, as that is treated as a PID in the other |
1348 | options, such as in \-\-join. | ||
1349 | .br | ||
1350 | For valid names, see the \fBNAME VALIDATION\fR section. | ||
1351 | .br | ||
1344 | 1352 | ||
1353 | .br | ||
1345 | In case the name supplied by the user is already in use by another sandbox, Firejail will assign a | 1354 | In case the name supplied by the user is already in use by another sandbox, Firejail will assign a |
1346 | new name as "name-PID", where PID is the process ID of the sandbox. This functionality | 1355 | new name as "name-PID", where PID is the process ID of the sandbox. This functionality |
1347 | can be disabled at run time in /etc/firejail/firejail.config file, by setting "name-change" flag to "no". | 1356 | can be disabled at run time in /etc/firejail/firejail.config file, by setting "name-change" flag to "no". |
@@ -3296,6 +3305,17 @@ Example: | |||
3296 | $ firejail --net=eth0 --x11=xephyr --xephyr-screen=640x480 firefox | 3305 | $ firejail --net=eth0 --x11=xephyr --xephyr-screen=640x480 firefox |
3297 | .br | 3306 | .br |
3298 | #endif | 3307 | #endif |
3308 | .\" Note: Keep this in sync with invalid_name() in src/firejail/util.c. | ||
3309 | .SH NAME VALIDATION | ||
3310 | For simplicity, the same name validation is used for multiple options. | ||
3311 | Rules: | ||
3312 | .PP | ||
3313 | The name must be 1-253 characters long. | ||
3314 | The name can only contain ASCII letters, digits and the special characters | ||
3315 | "-._" (that is, the name cannot contain spaces or control characters). | ||
3316 | The name cannot contain only digits. | ||
3317 | The first and last characters must be an ASCII letter or digit and the name | ||
3318 | may contain special characters in the middle. | ||
3299 | #ifdef HAVE_APPARMOR | 3319 | #ifdef HAVE_APPARMOR |
3300 | .SH APPARMOR | 3320 | .SH APPARMOR |
3301 | .TP | 3321 | .TP |