diff options
author | smitsohu <smitsohu@gmail.com> | 2021-10-05 18:11:50 +0200 |
---|---|---|
committer | smitsohu <smitsohu@gmail.com> | 2021-10-06 12:25:09 +0200 |
commit | a78d014660d8a1daaea95f11da399c2e2305cc63 (patch) | |
tree | 1c42b49afd5fce129c77781c7207a30e19a201ee /src | |
parent | simplify recursive remounting (diff) | |
download | firejail-a78d014660d8a1daaea95f11da399c2e2305cc63.tar.gz firejail-a78d014660d8a1daaea95f11da399c2e2305cc63.tar.zst firejail-a78d014660d8a1daaea95f11da399c2e2305cc63.zip |
mountinfo: get mount id from failed call to name_to_handle_at
Enables recursive remounting on very old kernels, which has some relevance
for SailfishOS community ports.
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/mountinfo.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/src/firejail/mountinfo.c b/src/firejail/mountinfo.c index f1eb9c924..304f80eee 100644 --- a/src/firejail/mountinfo.c +++ b/src/firejail/mountinfo.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include "firejail.h" | 21 | #include "firejail.h" |
22 | #include <errno.h> | ||
22 | 23 | ||
23 | #include <fcntl.h> | 24 | #include <fcntl.h> |
24 | #ifndef O_PATH | 25 | #ifndef O_PATH |
@@ -151,8 +152,35 @@ MountData *get_last_mount(void) { | |||
151 | return &mdata; | 152 | return &mdata; |
152 | } | 153 | } |
153 | 154 | ||
154 | // Needs kernel 3.15 or better | 155 | // Returns mount id, or -1 if fd refers to a procfs or sysfs file |
155 | int get_mount_id(int fd) { | 156 | static int get_mount_id_from_handle(int fd) { |
157 | EUID_ASSERT(); | ||
158 | |||
159 | char *proc; | ||
160 | if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) | ||
161 | errExit("asprintf"); | ||
162 | struct file_handle *fh = malloc(sizeof *fh); | ||
163 | if (!fh) | ||
164 | errExit("malloc"); | ||
165 | fh->handle_bytes = 0; | ||
166 | |||
167 | int rv = -1; | ||
168 | int tmp; | ||
169 | if (name_to_handle_at(-1, proc, fh, &tmp, AT_SYMLINK_FOLLOW) != -1) { | ||
170 | fprintf(stderr, "Error: unexpected result from name_to_handle_at\n"); | ||
171 | exit(1); | ||
172 | } | ||
173 | if (errno == EOVERFLOW && fh->handle_bytes) | ||
174 | rv = tmp; | ||
175 | |||
176 | free(proc); | ||
177 | free(fh); | ||
178 | return rv; | ||
179 | } | ||
180 | |||
181 | // Returns mount id, or -1 on kernels < 3.15 | ||
182 | static int get_mount_id_from_fdinfo(int fd) { | ||
183 | EUID_ASSERT(); | ||
156 | int rv = -1; | 184 | int rv = -1; |
157 | 185 | ||
158 | char *proc; | 186 | char *proc; |
@@ -182,6 +210,13 @@ errexit: | |||
182 | exit(1); | 210 | exit(1); |
183 | } | 211 | } |
184 | 212 | ||
213 | int get_mount_id(int fd) { | ||
214 | int rv = get_mount_id_from_fdinfo(fd); | ||
215 | if (rv < 0) | ||
216 | rv = get_mount_id_from_handle(fd); | ||
217 | return rv; | ||
218 | } | ||
219 | |||
185 | // Check /proc/self/mountinfo if path contains any mounts points. | 220 | // Check /proc/self/mountinfo if path contains any mounts points. |
186 | // Returns an array that can be iterated over for recursive remounting. | 221 | // Returns an array that can be iterated over for recursive remounting. |
187 | char **build_mount_array(const int mount_id, const char *path) { | 222 | char **build_mount_array(const int mount_id, const char *path) { |