aboutsummaryrefslogtreecommitdiffstats
path: root/src/jailcheck/access.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jailcheck/access.c')
-rw-r--r--src/jailcheck/access.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/jailcheck/access.c b/src/jailcheck/access.c
new file mode 100644
index 000000000..c18d64a82
--- /dev/null
+++ b/src/jailcheck/access.c
@@ -0,0 +1,143 @@
1/*
2 * Copyright (C) 2014-2021 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "jailcheck.h"
21#include <dirent.h>
22#include <sys/wait.h>
23
24typedef struct {
25 char *tfile;
26 char *tdir;
27} TestDir;
28
29#define MAX_TEST_FILES 16
30TestDir td[MAX_TEST_FILES];
31static int files_cnt = 0;
32
33void access_setup(const char *directory) {
34 // I am root!
35 assert(directory);
36 assert(user_home_dir);
37
38 if (files_cnt >= MAX_TEST_FILES) {
39 fprintf(stderr, "Error: maximum number of test directories exceded\n");
40 exit(1);
41 }
42
43 char *fname = strdup(directory);
44 if (!fname)
45 errExit("strdup");
46 if (strncmp(fname, "~/", 2) == 0) {
47 free(fname);
48 if (asprintf(&fname, "%s/%s", user_home_dir, directory + 2) == -1)
49 errExit("asprintf");
50 }
51
52 char *path = realpath(fname, NULL);
53 free(fname);
54 if (path == NULL) {
55 fprintf(stderr, "Warning: invalid directory %s, skipping...\n", directory);
56 return;
57 }
58
59 // file in home directory
60 if (strncmp(path, user_home_dir, strlen(user_home_dir)) != 0) {
61 fprintf(stderr, "Warning: file %s is not in user home directory, skipping...\n", directory);
62 free(path);
63 return;
64 }
65
66 // try to open the dir as root
67 DIR *dir = opendir(path);
68 if (!dir) {
69 fprintf(stderr, "Warning: directory %s not found, skipping\n", directory);
70 free(path);
71 return;
72 }
73 closedir(dir);
74
75 // create a test file
76 char *test_file;
77 if (asprintf(&test_file, "%s/jailcheck-access-%d", path, getpid()) == -1)
78 errExit("asprintf");
79
80 FILE *fp = fopen(test_file, "w");
81 if (!fp) {
82 printf("Warning: I cannot create test file in directory %s, skipping...\n", directory);
83 return;
84 }
85 fprintf(fp, "this file was created by firetest utility, you can safely delete it\n");
86 fclose(fp);
87 int rv = chown(test_file, user_uid, user_gid);
88 if (rv)
89 errExit("chown");
90
91 char *dname = strdup(directory);
92 if (!dname)
93 errExit("strdup");
94 td[files_cnt].tdir = dname;
95 td[files_cnt].tfile = test_file;
96 files_cnt++;
97}
98
99void access_destroy(void) {
100 // remove test files
101 int i;
102
103 for (i = 0; i < files_cnt; i++) {
104 int rv = unlink(td[i].tfile);
105 (void) rv;
106 }
107 files_cnt = 0;
108}
109
110void access_test(void) {
111 // I am root in sandbox mount namespace
112 assert(user_uid);
113 int i;
114
115 pid_t child = fork();
116 if (child == -1)
117 errExit("fork");
118
119 if (child == 0) { // child
120 // drop privileges
121 if (setgid(user_gid) != 0)
122 errExit("setgid");
123 if (setuid(user_uid) != 0)
124 errExit("setuid");
125
126 for (i = 0; i < files_cnt; i++) {
127 assert(td[i].tfile);
128
129 // try to open the file for reading
130 FILE *fp = fopen(td[i].tfile, "r");
131 if (fp) {
132
133 printf(" Warning: I can read %s\n", td[i].tdir);
134 fclose(fp);
135 }
136 }
137 exit(0);
138 }
139
140 // wait for the child to finish
141 int status;
142 wait(&status);
143}