summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorIago López Galeiras <iaguis@gmail.com>2015-10-15 12:13:13 +0200
committerIago López Galeiras <iaguis@gmail.com>2015-10-20 10:19:23 +0200
commitd167824896e583ffaca891b1c355ff852496ff66 (patch)
tree7a5e78bc85ee51a3b1639e8ffa75133eaff55ae8 /src/basic
parentec566e4c7cee67ec2c39475ef08f18a9f1b80efd (diff)
nspawn: skip /sys-as-tmpfs if we don't use private-network
Since v3.11/7dc5dbc ("sysfs: Restrict mounting sysfs"), the kernel doesn't allow mounting sysfs if you don't have CAP_SYS_ADMIN rights over the network namespace. So the mounting /sys as a tmpfs code introduced in d8fc6a000fe21b0c1ba27fbfed8b42d00b349a4b doesn't work with user namespaces if we don't use private-net. The reason is that we mount sysfs inside the container and we're in the network namespace of the host but we don't have CAP_SYS_ADMIN over that namespace. To fix that, we mount /sys as a sysfs (instead of tmpfs) if we don't use private network and ignore the /sys-as-a-tmpfs code if we find that /sys is already mounted as sysfs. Fixes #1555
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/util.c30
-rw-r--r--src/basic/util.h6
2 files changed, 33 insertions, 3 deletions
diff --git a/src/basic/util.c b/src/basic/util.c
index 2565b0f547..460e74061a 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -2500,11 +2500,35 @@ char *getusername_malloc(void) {
return lookup_uid(getuid());
}
-bool is_temporary_fs(const struct statfs *s) {
+bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) {
assert(s);
+ assert_cc(sizeof(statfs_f_type_t) >= sizeof(s->f_type));
+
+ return F_TYPE_EQUAL(s->f_type, magic_value);
+}
+
+int fd_check_fstype(int fd, statfs_f_type_t magic_value) {
+ struct statfs s;
+
+ if (fstatfs(fd, &s) < 0)
+ return -errno;
+
+ return is_fs_type(&s, magic_value);
+}
+
+int path_check_fstype(const char *path, statfs_f_type_t magic_value) {
+ _cleanup_close_ int fd = -1;
- return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
- F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return -errno;
+
+ return fd_check_fstype(fd, magic_value);
+}
+
+bool is_temporary_fs(const struct statfs *s) {
+ return is_fs_type(s, TMPFS_MAGIC) ||
+ is_fs_type(s, RAMFS_MAGIC);
}
int fd_is_temporary_fs(int fd) {
diff --git a/src/basic/util.h b/src/basic/util.h
index 6c63bc221f..ac74650ff6 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -365,6 +365,12 @@ char* getusername_malloc(void);
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
+typedef long statfs_f_type_t;
+
+bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) _pure_;
+int fd_check_fstype(int fd, statfs_f_type_t magic_value);
+int path_check_fstype(const char *path, statfs_f_type_t magic_value);
+
bool is_temporary_fs(const struct statfs *s) _pure_;
int fd_is_temporary_fs(int fd);