summaryrefslogtreecommitdiff
diff options
authorMichael Vogt <mvo@ubuntu.com>2019-07-15 13:48:06 +0200
committerMichael Vogt <mvo@ubuntu.com>2019-07-15 13:48:06 +0200
commit94c0c38e5779a9ae53e6fbc6643e65dc1bb91ae9 (patch)
treee97811a467fb4bb8174dda5fb0e651a797045868
parentbf765bad71f400c35b5dbb16bfd0acc093602059 (diff)
snap-confine: fallback gracefully on a cgroup v2 only system
On a cgroup v2 only system we cannot use certain features like freezer or pid cgroups yet. In order to not die() when we run on such systems this PR implements detection and skipping of those. This will have to be done "properly" but for now it ensures that snaps continue to run on cgroup v2 only systems.
-rw-r--r--cmd/libsnap-confine-private/cgroup-support.c16
-rw-r--r--cmd/libsnap-confine-private/cgroup-support.h7
-rw-r--r--cmd/snap-confine/ns-support.c3
-rw-r--r--cmd/snap-confine/snap-confine.c16
4 files changed, 36 insertions, 6 deletions
diff --git a/cmd/libsnap-confine-private/cgroup-support.c b/cmd/libsnap-confine-private/cgroup-support.c
index 03dc4b160f..c61d516a47 100644
--- a/cmd/libsnap-confine-private/cgroup-support.c
+++ b/cmd/libsnap-confine-private/cgroup-support.c
@@ -25,6 +25,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/vfs.h>
#include <unistd.h>
#include "cleanup-funcs.h"
@@ -66,3 +67,18 @@ void sc_cgroup_create_and_join(const char *parent, const char *name, pid_t pid)
}
debug("moved process %ld to cgroup hierarchy %s/%s", (long)pid, parent, name);
}
+
+static const char *cgroup_dir = "/sys/fs/cgroup";
+// from statfs(2)
+static const int CGROUP2_SUPER_MAGIC = 0x63677270;
+
+bool sc_cgroup_is_v2() {
+ struct statfs buf;
+
+ int err = statfs(cgroup_dir, &buf);
+ if (err == 0 && buf.f_type == CGROUP2_SUPER_MAGIC) {
+ fprintf(stderr, "WARNING: cgroup v2 is not fully supported yet\n");
+ return true;
+ }
+ return false;
+}
diff --git a/cmd/libsnap-confine-private/cgroup-support.h b/cmd/libsnap-confine-private/cgroup-support.h
index 33e5ccc90b..f7f0ebaf9b 100644
--- a/cmd/libsnap-confine-private/cgroup-support.h
+++ b/cmd/libsnap-confine-private/cgroup-support.h
@@ -19,6 +19,7 @@
#define SC_CGROUP_SUPPORT_H
#include <fcntl.h>
+#include <stdbool.h>
/**
* sc_cgroup_create_and_join joins, perhaps creating, a cgroup hierarchy.
@@ -30,4 +31,10 @@
**/
void sc_cgroup_create_and_join(const char *parent, const char *name, pid_t pid);
+/**
+ * sc_cgroup_is_v2() returns true if running on cgroups v2
+ *
+ **/
+bool sc_cgroup_is_v2(void);
+
#endif
diff --git a/cmd/snap-confine/ns-support.c b/cmd/snap-confine/ns-support.c
index 672f18b6a0..c3d958b113 100644
--- a/cmd/snap-confine/ns-support.c
+++ b/cmd/snap-confine/ns-support.c
@@ -39,6 +39,7 @@
#include <unistd.h>
#include "../libsnap-confine-private/cgroup-freezer-support.h"
+#include "../libsnap-confine-private/cgroup-support.h"
#include "../libsnap-confine-private/classic.h"
#include "../libsnap-confine-private/cleanup-funcs.h"
#include "../libsnap-confine-private/infofile.h"
@@ -486,7 +487,7 @@ static int sc_inspect_and_maybe_discard_stale_ns(int mnt_fd,
debug("preserved mount is not stale, reusing");
return 0;
case SC_DISCARD_SHOULD:
- if (sc_cgroup_freezer_occupied(inv->snap_instance)) {
+ if (!sc_cgroup_is_v2() && sc_cgroup_freezer_occupied(inv->snap_instance)) {
// Some processes are still using the namespace so we cannot discard it
// as that would fracture the view that the set of processes inside
// have on what is mounted.
diff --git a/cmd/snap-confine/snap-confine.c b/cmd/snap-confine/snap-confine.c
index ac2f0375df..a4f4988326 100644
--- a/cmd/snap-confine/snap-confine.c
+++ b/cmd/snap-confine/snap-confine.c
@@ -35,6 +35,7 @@
#include "../libsnap-confine-private/apparmor-support.h"
#include "../libsnap-confine-private/cgroup-freezer-support.h"
#include "../libsnap-confine-private/cgroup-pids-support.h"
+#include "../libsnap-confine-private/cgroup-support.h"
#include "../libsnap-confine-private/classic.h"
#include "../libsnap-confine-private/cleanup-funcs.h"
#include "../libsnap-confine-private/feature.h"
@@ -574,8 +575,11 @@ static void enter_non_classic_execution_environment(sc_invocation * inv,
/** Populate and join the device control group. */
struct snappy_udev udev_s;
- if (snappy_udev_init(inv->security_tag, &udev_s) == 0)
- setup_devices_cgroup(inv->security_tag, &udev_s);
+ if (snappy_udev_init(inv->security_tag, &udev_s) == 0) {
+ if (sc_cgroup_is_v2()) {
+ setup_devices_cgroup(inv->security_tag, &udev_s);
+ }
+ }
snappy_udev_cleanup(&udev_s);
/**
@@ -675,9 +679,11 @@ static void enter_non_classic_execution_environment(sc_invocation * inv,
die("cannot set effective group id to root");
}
}
- sc_cgroup_freezer_join(inv->snap_instance, getpid());
- if (sc_feature_enabled(SC_FEATURE_REFRESH_APP_AWARENESS)) {
- sc_cgroup_pids_join(inv->security_tag, getpid());
+ if (!sc_cgroup_is_v2()) {
+ sc_cgroup_freezer_join(inv->snap_instance, getpid());
+ if (sc_feature_enabled(SC_FEATURE_REFRESH_APP_AWARENESS)) {
+ sc_cgroup_pids_join(inv->security_tag, getpid());
+ }
}
if (geteuid() == 0 && real_gid != 0) {
if (setegid(real_gid) != 0) {