aboutsummaryrefslogtreecommitdiffstats
path: root/src/fcopy/main.c
diff options
context:
space:
mode:
authorLibravatar Simo Piiroinen <simo.piiroinen@jolla.com>2020-10-09 12:15:31 +0300
committerLibravatar Tomi Leppänen <tomi.leppanen@jolla.com>2021-02-19 09:38:54 +0200
commit80b73e75d82ec618625c5278828bb5b9b32d3114 (patch)
treeba062f63d9c343a47898b089d20d28cf24ca9f44 /src/fcopy/main.c
parentrefresh capabilities (#3945) (diff)
downloadfirejail-80b73e75d82ec618625c5278828bb5b9b32d3114.tar.gz
firejail-80b73e75d82ec618625c5278828bb5b9b32d3114.tar.zst
firejail-80b73e75d82ec618625c5278828bb5b9b32d3114.zip
Fix symlinks that go though /proc/self
When constructing sandbox fs, /etc/mtab which is symlink to /proc/self/mounts gets resolved as /proc/PID/mounts. Where PID is not the pid of the process that is going to get executed in the firejail -> the result is broken/unaccessible symlink from the application point of view. Use /proc/self/xxx type symlink target if it resolves similarly as the /proc/PID/xxx type would at the time of mapping. Signed-off-by: Simo Piiroinen <simo.piiroinen@jolla.com> Signed-off-by: Tomi Leppänen <tomi.leppanen@jolla.com>
Diffstat (limited to 'src/fcopy/main.c')
-rw-r--r--src/fcopy/main.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/src/fcopy/main.c b/src/fcopy/main.c
index 01633be59..a41df52a1 100644
--- a/src/fcopy/main.c
+++ b/src/fcopy/main.c
@@ -172,6 +172,47 @@ static void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid) {
172 } 172 }
173} 173}
174 174
175static char *proc_pid_to_self(const char *target)
176{
177 char *use_target = 0;
178 char *proc_pid = 0;
179
180 if (!(use_target = canonicalize_file_name(target)))
181 goto done;
182
183 // target is under /proc/<PID>?
184 static const char proc[] = "/proc/";
185 if (strncmp(use_target, proc, sizeof proc - 1))
186 goto done;
187
188 int digit = use_target[sizeof proc - 1];
189 if (digit < '1' || digit > '9')
190 goto done;
191
192 // check where /proc/self points to
193 static const char proc_self[] = "/proc/self";
194 if (!(proc_pid = canonicalize_file_name(proc_self)))
195 goto done;
196
197 // redirect /proc/PID/xxx -> /proc/self/XXX
198 size_t pfix = strlen(proc_pid);
199 if (strncmp(use_target, proc_pid, pfix))
200 goto done;
201
202 if (use_target[pfix] != 0 && use_target[pfix] != '/')
203 goto done;
204
205 char *tmp;
206 if (asprintf(&tmp, "%s%s", proc_self, use_target + pfix) != -1) {
207 if (arg_debug)
208 fprintf(stderr, "SYMLINK %s\n --> %s\n", use_target, tmp);
209 free(use_target), use_target = tmp;
210 }
211
212done:
213 free(proc_pid);
214 return use_target;
215}
175 216
176void copy_link(const char *target, const char *linkpath, mode_t mode, uid_t uid, gid_t gid) { 217void copy_link(const char *target, const char *linkpath, mode_t mode, uid_t uid, gid_t gid) {
177 (void) mode; 218 (void) mode;
@@ -183,7 +224,7 @@ void copy_link(const char *target, const char *linkpath, mode_t mode, uid_t uid,
183 if (lstat(linkpath, &s) == 0) 224 if (lstat(linkpath, &s) == 0)
184 return; 225 return;
185 226
186 char *rp = realpath(target, NULL); 227 char *rp = proc_pid_to_self(target);
187 if (rp) { 228 if (rp) {
188 if (symlink(rp, linkpath) == -1) { 229 if (symlink(rp, linkpath) == -1) {
189 free(rp); 230 free(rp);