aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/firejail/firejail.h3
-rw-r--r--src/firejail/main.c70
-rw-r--r--src/firejail/util.c70
3 files changed, 74 insertions, 69 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 49d19e33d..85139d75f 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -528,6 +528,9 @@ void disable_file_path(const char *path, const char *file);
528int safe_fd(const char *path, int flags); 528int safe_fd(const char *path, int flags);
529int has_handler(pid_t pid, int signal); 529int has_handler(pid_t pid, int signal);
530void enter_network_namespace(pid_t pid); 530void enter_network_namespace(pid_t pid);
531int read_pid(const char *name, pid_t *pid);
532pid_t require_pid(const char *name);
533void check_homedir(void);
531 534
532// Get info regarding the last kernel mount operation from /proc/self/mountinfo 535// Get info regarding the last kernel mount operation from /proc/self/mountinfo
533// The return value points to a static area, and will be overwritten by subsequent calls. 536// The return value points to a static area, and will be overwritten by subsequent calls.
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 072651c4d..df890ecea 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -31,7 +31,7 @@
31#include <dirent.h> 31#include <dirent.h>
32#include <pwd.h> 32#include <pwd.h>
33#include <errno.h> 33#include <errno.h>
34#include <limits.h> 34//#include <limits.h>
35#include <sys/file.h> 35#include <sys/file.h>
36#include <sys/prctl.h> 36#include <sys/prctl.h>
37#include <signal.h> 37#include <signal.h>
@@ -215,74 +215,6 @@ static void install_handler(void) {
215 sigaction(SIGTERM, &sga, NULL); 215 sigaction(SIGTERM, &sga, NULL);
216} 216}
217 217
218// return 1 if error, 0 if a valid pid was found
219static int extract_pid(const char *name, pid_t *pid) {
220 int retval = 0;
221 EUID_ASSERT();
222 if (!name || strlen(name) == 0) {
223 fprintf(stderr, "Error: invalid sandbox name\n");
224 exit(1);
225 }
226
227 EUID_ROOT();
228 if (name2pid(name, pid)) {
229 retval = 1;
230 }
231 EUID_USER();
232 return retval;
233}
234
235// return 1 if error, 0 if a valid pid was found
236static int read_pid(const char *name, pid_t *pid) {
237 char *endptr;
238 errno = 0;
239 long int pidtmp = strtol(name, &endptr, 10);
240 if ((errno == ERANGE && (pidtmp == LONG_MAX || pidtmp == LONG_MIN))
241 || (errno != 0 && pidtmp == 0)) {
242 return extract_pid(name,pid);
243 }
244 // endptr points to '\0' char in name if the entire string is valid
245 if (endptr == NULL || endptr[0]!='\0') {
246 return extract_pid(name,pid);
247 }
248 *pid =(pid_t)pidtmp;
249 return 0;
250}
251
252static pid_t require_pid(const char *name) {
253 pid_t pid;
254 if (read_pid(name,&pid)) {
255 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
256 exit(1);
257 }
258 return pid;
259}
260
261// return 1 if there is a link somewhere in path of directory
262static int has_link(const char *dir) {
263 assert(dir);
264 int fd = safe_fd(dir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
265 if (fd == -1) {
266 if (errno == ENOTDIR && is_dir(dir))
267 return 1;
268 }
269 else
270 close(fd);
271 return 0;
272}
273
274static void check_homedir(void) {
275 assert(cfg.homedir);
276 if (cfg.homedir[0] != '/') {
277 fprintf(stderr, "Error: invalid user directory \"%s\"\n", cfg.homedir);
278 exit(1);
279 }
280 // symlinks are rejected in many places
281 if (has_link(cfg.homedir)) {
282 fprintf(stderr, "No full support for symbolic links in path of user directory.\n"
283 "Please provide resolved path in password database (/etc/passwd).\n\n");
284 }
285}
286 218
287// init configuration 219// init configuration
288static void init_cfg(int argc, char **argv) { 220static void init_cfg(int argc, char **argv) {
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 3aa0584d6..d65ac0071 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -29,6 +29,7 @@
29#include <sys/ioctl.h> 29#include <sys/ioctl.h>
30#include <termios.h> 30#include <termios.h>
31#include <sys/wait.h> 31#include <sys/wait.h>
32#include <limits.h>
32 33
33#include <fcntl.h> 34#include <fcntl.h>
34#ifndef O_PATH 35#ifndef O_PATH
@@ -1265,3 +1266,72 @@ void enter_network_namespace(pid_t pid) {
1265 exit(1); 1266 exit(1);
1266 } 1267 }
1267} 1268}
1269
1270// return 1 if error, 0 if a valid pid was found
1271static int extract_pid(const char *name, pid_t *pid) {
1272 int retval = 0;
1273 EUID_ASSERT();
1274 if (!name || strlen(name) == 0) {
1275 fprintf(stderr, "Error: invalid sandbox name\n");
1276 exit(1);
1277 }
1278
1279 EUID_ROOT();
1280 if (name2pid(name, pid)) {
1281 retval = 1;
1282 }
1283 EUID_USER();
1284 return retval;
1285}
1286
1287// return 1 if error, 0 if a valid pid was found
1288int read_pid(const char *name, pid_t *pid) {
1289 char *endptr;
1290 errno = 0;
1291 long int pidtmp = strtol(name, &endptr, 10);
1292 if ((errno == ERANGE && (pidtmp == LONG_MAX || pidtmp == LONG_MIN))
1293 || (errno != 0 && pidtmp == 0)) {
1294 return extract_pid(name,pid);
1295 }
1296 // endptr points to '\0' char in name if the entire string is valid
1297 if (endptr == NULL || endptr[0]!='\0') {
1298 return extract_pid(name,pid);
1299 }
1300 *pid =(pid_t)pidtmp;
1301 return 0;
1302}
1303
1304pid_t require_pid(const char *name) {
1305 pid_t pid;
1306 if (read_pid(name,&pid)) {
1307 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
1308 exit(1);
1309 }
1310 return pid;
1311}
1312
1313// return 1 if there is a link somewhere in path of directory
1314static int has_link(const char *dir) {
1315 assert(dir);
1316 int fd = safe_fd(dir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
1317 if (fd == -1) {
1318 if (errno == ENOTDIR && is_dir(dir))
1319 return 1;
1320 }
1321 else
1322 close(fd);
1323 return 0;
1324}
1325
1326void check_homedir(void) {
1327 assert(cfg.homedir);
1328 if (cfg.homedir[0] != '/') {
1329 fprintf(stderr, "Error: invalid user directory \"%s\"\n", cfg.homedir);
1330 exit(1);
1331 }
1332 // symlinks are rejected in many places
1333 if (has_link(cfg.homedir)) {
1334 fprintf(stderr, "No full support for symbolic links in path of user directory.\n"
1335 "Please provide resolved path in password database (/etc/passwd).\n\n");
1336 }
1337}