aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/fs_home.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-01-10 10:07:20 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2017-01-10 10:07:20 -0500
commit9aa81442afc6e00ca177bf0e3e7a025195102f7d (patch)
treecedef10be6c5efa2b3a87ec2568836891e696c61 /src/firejail/fs_home.c
parentMerge pull request #1027 from reinerh/cve-references2 (diff)
downloadfirejail-9aa81442afc6e00ca177bf0e3e7a025195102f7d.tar.gz
firejail-9aa81442afc6e00ca177bf0e3e7a025195102f7d.tar.zst
firejail-9aa81442afc6e00ca177bf0e3e7a025195102f7d.zip
security fix
Diffstat (limited to 'src/firejail/fs_home.c')
-rw-r--r--src/firejail/fs_home.c148
1 files changed, 36 insertions, 112 deletions
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index 4de082b06..e4b19d5cc 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -42,19 +42,17 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
42 // don't copy it if we already have the file 42 // don't copy it if we already have the file
43 if (stat(fname, &s) == 0) 43 if (stat(fname, &s) == 0)
44 return; 44 return;
45 if (is_link(fname)) { // stat on dangling symlinks fails, try again using lstat
46 fprintf(stderr, "Error: invalid %s file\n", fname);
47 exit(1);
48 }
45 if (stat("/etc/skel/.zshrc", &s) == 0) { 49 if (stat("/etc/skel/.zshrc", &s) == 0) {
46 if (copy_file("/etc/skel/.zshrc", fname, u, g, 0644) == 0) { 50 copy_file_as_user("/etc/skel/.zshrc", fname, u, g, 0644);
47 fs_logger("clone /etc/skel/.zshrc"); 51 fs_logger("clone /etc/skel/.zshrc");
48 }
49 } 52 }
50 else { // 53 else {
51 FILE *fp = fopen(fname, "w"); 54 touch_file_as_user(fname, u, g, 0644);
52 if (fp) { 55 fs_logger2("touch", fname);
53 fprintf(fp, "\n");
54 SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR);
55 fclose(fp);
56 fs_logger2("touch", fname);
57 }
58 } 56 }
59 free(fname); 57 free(fname);
60 } 58 }
@@ -64,23 +62,21 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
64 if (asprintf(&fname, "%s/.cshrc", homedir) == -1) 62 if (asprintf(&fname, "%s/.cshrc", homedir) == -1)
65 errExit("asprintf"); 63 errExit("asprintf");
66 struct stat s; 64 struct stat s;
65
67 // don't copy it if we already have the file 66 // don't copy it if we already have the file
68 if (stat(fname, &s) == 0) 67 if (stat(fname, &s) == 0)
69 return; 68 return;
69 if (is_link(fname)) { // stat on dangling symlinks fails, try again using lstat
70 fprintf(stderr, "Error: invalid %s file\n", fname);
71 exit(1);
72 }
70 if (stat("/etc/skel/.cshrc", &s) == 0) { 73 if (stat("/etc/skel/.cshrc", &s) == 0) {
71 if (copy_file("/etc/skel/.cshrc", fname, u, g, 0644) == 0) { 74 copy_file_as_user("/etc/skel/.cshrc", fname, u, g, 0644);
72 fs_logger("clone /etc/skel/.cshrc"); 75 fs_logger("clone /etc/skel/.cshrc");
73 }
74 } 76 }
75 else { // 77 else {
76 /* coverity[toctou] */ 78 touch_file_as_user(fname, u, g, 0644);
77 FILE *fp = fopen(fname, "w"); 79 fs_logger2("touch", fname);
78 if (fp) {
79 fprintf(fp, "\n");
80 SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR);
81 fclose(fp);
82 fs_logger2("touch", fname);
83 }
84 } 80 }
85 free(fname); 81 free(fname);
86 } 82 }
@@ -93,10 +89,13 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
93 // don't copy it if we already have the file 89 // don't copy it if we already have the file
94 if (stat(fname, &s) == 0) 90 if (stat(fname, &s) == 0)
95 return; 91 return;
92 if (is_link(fname)) { // stat on dangling symlinks fails, try again using lstat
93 fprintf(stderr, "Error: invalid %s file\n", fname);
94 exit(1);
95 }
96 if (stat("/etc/skel/.bashrc", &s) == 0) { 96 if (stat("/etc/skel/.bashrc", &s) == 0) {
97 if (copy_file("/etc/skel/.bashrc", fname, u, g, 0644) == 0) { 97 copy_file_as_user("/etc/skel/.bashrc", fname, u, g, 0644);
98 fs_logger("clone /etc/skel/.bashrc"); 98 fs_logger("clone /etc/skel/.bashrc");
99 }
100 } 99 }
101 free(fname); 100 free(fname);
102 } 101 }
@@ -106,7 +105,7 @@ static int store_xauthority(void) {
106 // put a copy of .Xauthority in XAUTHORITY_FILE 105 // put a copy of .Xauthority in XAUTHORITY_FILE
107 char *src; 106 char *src;
108 char *dest = RUN_XAUTHORITY_FILE; 107 char *dest = RUN_XAUTHORITY_FILE;
109 // create an empty file 108 // create an empty file as root, and change ownership to user
110 FILE *fp = fopen(dest, "w"); 109 FILE *fp = fopen(dest, "w");
111 if (fp) { 110 if (fp) {
112 fprintf(fp, "\n"); 111 fprintf(fp, "\n");
@@ -124,27 +123,8 @@ static int store_xauthority(void) {
124 return 0; 123 return 0;
125 } 124 }
126 125
127 pid_t child = fork(); 126 copy_file_as_user(src, dest, getuid(), getgid(), 0600);
128 if (child < 0) 127 fs_logger2("clone", dest);
129 errExit("fork");
130 if (child == 0) {
131 // drop privileges
132 drop_privs(0);
133
134 // copy, set permissions and ownership
135 int rv = copy_file(src, dest, getuid(), getgid(), 0600);
136 if (rv)
137 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
138 else {
139 fs_logger2("clone", dest);
140 }
141#ifdef HAVE_GCOV
142 __gcov_flush();
143#endif
144 _exit(0);
145 }
146 // wait for the child to finish
147 waitpid(child, NULL, 0);
148 return 1; // file copied 128 return 1; // file copied
149 } 129 }
150 130
@@ -152,9 +132,10 @@ static int store_xauthority(void) {
152} 132}
153 133
154static int store_asoundrc(void) { 134static int store_asoundrc(void) {
135 // put a copy of .Xauthority in XAUTHORITY_FILE
155 char *src; 136 char *src;
156 char *dest = RUN_ASOUNDRC_FILE; 137 char *dest = RUN_ASOUNDRC_FILE;
157 // create an empty file 138 // create an empty file as root, and change ownership to user
158 FILE *fp = fopen(dest, "w"); 139 FILE *fp = fopen(dest, "w");
159 if (fp) { 140 if (fp) {
160 fprintf(fp, "\n"); 141 fprintf(fp, "\n");
@@ -182,27 +163,8 @@ static int store_asoundrc(void) {
182 free(rp); 163 free(rp);
183 } 164 }
184 165
185 pid_t child = fork(); 166 copy_file_as_user(src, dest, getuid(), getgid(), 0644);
186 if (child < 0) 167 fs_logger2("clone", dest);
187 errExit("fork");
188 if (child == 0) {
189 // drop privileges
190 drop_privs(0);
191
192 // copy, set permissions and ownership
193 int rv = copy_file(src, dest, getuid(), getgid(), 0644);
194 if (rv)
195 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
196 else {
197 fs_logger2("clone", dest);
198 }
199#ifdef HAVE_GCOV
200 __gcov_flush();
201#endif
202 _exit(0);
203 }
204 // wait for the child to finish
205 waitpid(child, NULL, 0);
206 return 1; // file copied 168 return 1; // file copied
207 } 169 }
208 170
@@ -222,27 +184,8 @@ static void copy_xauthority(void) {
222 exit(1); 184 exit(1);
223 } 185 }
224 186
225 pid_t child = fork(); 187 copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
226 if (child < 0) 188 fs_logger2("clone", dest);
227 errExit("fork");
228 if (child == 0) {
229 // drop privileges
230 drop_privs(0);
231
232 // copy, set permissions and ownership
233 int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
234 if (rv)
235 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
236 else {
237 fs_logger2("clone", dest);
238 }
239#ifdef HAVE_GCOV
240 __gcov_flush();
241#endif
242 _exit(0);
243 }
244 // wait for the child to finish
245 waitpid(child, NULL, 0);
246 189
247 // delete the temporary file 190 // delete the temporary file
248 unlink(src); 191 unlink(src);
@@ -261,27 +204,8 @@ static void copy_asoundrc(void) {
261 exit(1); 204 exit(1);
262 } 205 }
263 206
264 pid_t child = fork(); 207 copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
265 if (child < 0) 208 fs_logger2("clone", dest);
266 errExit("fork");
267 if (child == 0) {
268 // drop privileges
269 drop_privs(0);
270
271 // copy, set permissions and ownership
272 int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
273 if (rv)
274 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
275 else {
276 fs_logger2("clone", dest);
277 }
278#ifdef HAVE_GCOV
279 __gcov_flush();
280#endif
281 _exit(0);
282 }
283 // wait for the child to finish
284 waitpid(child, NULL, 0);
285 209
286 // delete the temporary file 210 // delete the temporary file
287 unlink(src); 211 unlink(src);