[glick2] If we can't do the final bind mount, instead use a private tmpfs mount and a symlink
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glick2] If we can't do the final bind mount, instead use a private tmpfs mount and a symlink
- Date: Tue, 22 Nov 2011 13:44:42 +0000 (UTC)
commit 0bd1f7ad5c4edfc9f0887421798d25c4fe89aa3f
Author: Alexander Larsson <alexl redhat com>
Date: Tue Nov 22 14:37:31 2011 +0100
If we can't do the final bind mount, instead use a private tmpfs mount and a symlink
helper.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 47 insertions(+), 8 deletions(-)
---
diff --git a/helper.c b/helper.c
index 67e28db..e3b2446 100644
--- a/helper.c
+++ b/helper.c
@@ -80,6 +80,7 @@ main (int argc,
char **child_argv;
int i, j, fd, argv_offset;
int mount_count;
+ int use_tmpfs;
/* The initial code is run with a high permission euid
(at least CAP_SYS_ADMIN), so take lots of care. */
@@ -160,27 +161,65 @@ main (int argc,
}
}
- __debug__(("mount source\n"));
+ use_tmpfs = 0;
+ __debug__(("mount source %s to %s\n", mount_source, BUNDLE_PREFIX));
res = mount (mount_source, BUNDLE_PREFIX,
NULL, MS_BIND, NULL);
- if (res != 0) {
- perror ("Failed to bind the source directory");
- goto error_out;
- }
+ if (res != 0)
+ {
+ int errsv = errno;
+ printf ("errno: %d\n", errsv);
+ if (errsv == EACCES)
+ {
+ /* Some older kernels don't allow bind mounting (as root) a file
+ inside a (non-root) fuse mount (as the uid differs). For these
+ cases we create a private tmpfs mount with a symlink in */
+ res = mount ("tmpfs" , BUNDLE_PREFIX,
+ "tmpfs", MS_NODEV|MS_NOEXEC, NULL);
+
+ if (res != 0)
+ {
+ perror ("Failed to mount tmpfs");
+ goto error_out;
+ }
+
+ use_tmpfs = 1;
+ }
+ else
+ {
+ perror ("Failed to bind the source directory");
+ goto error_out;
+ }
+ }
mount_count++; /* Normal mount succeeded */
/* Now we have everything we need CAP_SYS_ADMIN for, so drop setuid */
setuid (getuid ());
+ executable = NULL;
+ child_argv = NULL;
+
+ if (use_tmpfs)
+ {
+ char *mount_source_data = strconcat (mount_source, "/data", NULL);
+ if (mount_source_data == NULL)
+ goto oom;
+ res = symlink (mount_source_data, BUNDLE_PREFIX "/data");
+ if (res != 0)
+ {
+ perror ("Unable to create symlink");
+ free (mount_source_data);
+ goto error_out;
+ }
+ free (mount_source_data);
+ }
+
if (fd != 0)
{
char c = 'x';
write (fd, &c, 1);
}
- executable = NULL;
- child_argv = NULL;
-
if (executable_relative[0] == '/')
executable = executable_relative;
else
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]