aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/preproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail/preproc.c')
-rw-r--r--src/firejail/preproc.c96
1 files changed, 95 insertions, 1 deletions
diff --git a/src/firejail/preproc.c b/src/firejail/preproc.c
index 2c7d4264d..e0ca2141f 100644
--- a/src/firejail/preproc.c
+++ b/src/firejail/preproc.c
@@ -18,15 +18,101 @@
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20#include "firejail.h" 20#include "firejail.h"
21#include <sys/file.h>
21#include <sys/mount.h> 22#include <sys/mount.h>
22#include <sys/stat.h> 23#include <sys/stat.h>
23#include <sys/types.h> 24#include <sys/types.h>
24#include <dirent.h> 25#include <dirent.h>
26#include <fcntl.h>
25 27
26static int tmpfs_mounted = 0; 28static int tmpfs_mounted = 0;
27 29
30static void preproc_lock_file(const char *path, int *lockfd_ptr) {
31 assert(path != NULL);
32 assert(lockfd_ptr != NULL);
33
34 long pid = (long)getpid();
35 if (arg_debug)
36 fprintf(stderr, "pid=%ld: locking %s ...\n", pid, path);
37
38 if (*lockfd_ptr != -1) {
39 if (arg_debug)
40 fprintf(stderr, "pid=%ld: already locked %s\n", pid, path);
41 return;
42 }
43
44 int lockfd = open(path, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
45 if (lockfd == -1) {
46 fprintf(stderr, "Error: cannot create a lockfile at %s\n", path);
47 errExit("open");
48 }
49
50 if (fchown(lockfd, 0, 0) == -1) {
51 fprintf(stderr, "Error: cannot chown root:root %s\n", path);
52 errExit("fchown");
53 }
54
55 if (flock(lockfd, LOCK_EX) == -1) {
56 fprintf(stderr, "Error: cannot lock %s\n", path);
57 errExit("flock");
58 }
59
60 *lockfd_ptr = lockfd;
61 if (arg_debug)
62 fprintf(stderr, "pid=%ld: locked %s\n", pid, path);
63}
64
65static void preproc_unlock_file(const char *path, int *lockfd_ptr) {
66 assert(path != NULL);
67 assert(lockfd_ptr != NULL);
68
69 long pid = (long)getpid();
70 if (arg_debug)
71 fprintf(stderr, "pid=%ld: unlocking %s ...\n", pid, path);
72
73 int lockfd = *lockfd_ptr;
74 if (lockfd == -1) {
75 if (arg_debug)
76 fprintf(stderr, "pid=%ld: already unlocked %s\n", pid, path);
77 return;
78 }
79
80 if (flock(lockfd, LOCK_UN) == -1) {
81 fprintf(stderr, "Error: cannot unlock %s\n", path);
82 errExit("flock");
83 }
84
85 if (close(lockfd) == -1) {
86 fprintf(stderr, "Error: cannot close %s\n", path);
87 errExit("close");
88 }
89
90 *lockfd_ptr = -1;
91 if (arg_debug)
92 fprintf(stderr, "pid=%ld: unlocked %s\n", pid, path);
93}
94
95void preproc_lock_firejail_dir(void) {
96 preproc_lock_file(RUN_DIRECTORY_LOCK_FILE, &lockfd_directory);
97}
98
99void preproc_unlock_firejail_dir(void) {
100 preproc_unlock_file(RUN_DIRECTORY_LOCK_FILE, &lockfd_directory);
101}
102
103void preproc_lock_firejail_network_dir(void) {
104 preproc_lock_file(RUN_NETWORK_LOCK_FILE, &lockfd_network);
105}
106
107void preproc_unlock_firejail_network_dir(void) {
108 preproc_unlock_file(RUN_NETWORK_LOCK_FILE, &lockfd_network);
109}
110
28// build /run/firejail directory 111// build /run/firejail directory
29void preproc_build_firejail_dir(void) { 112//
113// Note: This creates the base directory of the rundir lockfile;
114// it should be called before preproc_lock_firejail_dir().
115void preproc_build_firejail_dir_unlocked(void) {
30 struct stat s; 116 struct stat s;
31 117
32 // CentOS 6 doesn't have /run directory 118 // CentOS 6 doesn't have /run directory
@@ -35,6 +121,14 @@ void preproc_build_firejail_dir(void) {
35 } 121 }
36 122
37 create_empty_dir_as_root(RUN_FIREJAIL_DIR, 0755); 123 create_empty_dir_as_root(RUN_FIREJAIL_DIR, 0755);
124}
125
126// build directory hierarchy under /run/firejail
127//
128// Note: Remounts have timing hazards. This function should
129// only be called after acquiring the directory lock via
130// preproc_lock_firejail_dir().
131void preproc_build_firejail_dir_locked(void) {
38 create_empty_dir_as_root(RUN_FIREJAIL_NETWORK_DIR, 0755); 132 create_empty_dir_as_root(RUN_FIREJAIL_NETWORK_DIR, 0755);
39 create_empty_dir_as_root(RUN_FIREJAIL_BANDWIDTH_DIR, 0755); 133 create_empty_dir_as_root(RUN_FIREJAIL_BANDWIDTH_DIR, 0755);
40 create_empty_dir_as_root(RUN_FIREJAIL_NAME_DIR, 0755); 134 create_empty_dir_as_root(RUN_FIREJAIL_NAME_DIR, 0755);