]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
Add support for nosuid, noexec and nodev
authorBalbir Singh <bsingharora@gmail.com>
Fri, 12 Oct 2018 08:57:24 +0000 (10:57 +0200)
committerNikola Forró <nforro@redhat.com>
Fri, 12 Oct 2018 08:57:24 +0000 (10:57 +0200)
Inspired by the contents of https://lwn.net/Articles/647757/, there
is no easy way of passing these mount options with cgroups. For existing
users, it makes sense to support these

Signed-off-by: Balbir Singh <bsingharora@gmail.com>
Acked-by: Nikola Forró <nforro@redhat.com>
doc/man/cgconfig.conf.5
src/config.c

index f3a4ba91c1d7574776371435e6fe2e03590a2b85..2a5c4eef4b8d15ab06b5fd067a70662e0675c478 100644 (file)
@@ -43,7 +43,9 @@ can be found in
 .I /proc/cgroups
 file. Named hierarchy can be specified as controller
 \fB"name=<somename>"\fR. Do not forget to use double quotes around
-this controller name (see examples below).
+this controller name (see examples below). Apart from named hierarchy,
+additional mount options may be specified by putting the controller and
+the options in quotes. Options supported are \fB nosuid, noexec\fR and\fB nodev\fR.
 
 .B Libcgroup
 merges all subsystems mounted to the same directory (see
@@ -765,6 +767,26 @@ mkdir /mnt/cgroups/cpuacct/daemons
 The situation is the similar as in Example 4. The only difference is template,
 which is used if some rule uses "/students/%u" as a destination.
 
+.SS Example 8
+.LP
+The configuration file:
+
+.LP
+.RS
+.nf
+mount {
+.RS
+"cpu,nodev,nosuid,noexec" = /mnt/cgroups/cpu;
+.RE
+}
+
+.fi
+.RE
+
+This is the same as
+mount -t cgroup cgroup -o nodev,nosuid,noexec,cpu /mnt/cgroups/cpu
+It mounts the cpu controller with MS_NODEV, MS_NOSUID and MS_NOEXEC
+options passed.
 
 
 .SH RECOMMENDATIONS
index 090bea56e4a0e3ec4359564868554d26fd8c592e..5a0b39ba0412f68c7f6ac86de01b723c396c216d 100644 (file)
@@ -629,13 +629,16 @@ void cgroup_config_cleanup_namespace_table(void)
  * Add necessary options for mount. Currently only 'none' option is added
  * for mounts with only 'name=xxx' and without real controller.
  */
-static int cgroup_config_ajdust_mount_options(struct cg_mount_table_s *mount)
+static int cgroup_config_ajdust_mount_options(struct cg_mount_table_s *mount,
+                                               unsigned long *flags)
 {
        char *save = NULL;
        char *opts = strdup(mount->name);
        char *token;
        int name_only = 1;
+       char *controller= NULL;
 
+       *flags = 0;
        if (opts == NULL)
                return ECGFAIL;
 
@@ -643,12 +646,39 @@ static int cgroup_config_ajdust_mount_options(struct cg_mount_table_s *mount)
        while (token != NULL) {
                if (strncmp(token, "name=", 5) != 0) {
                        name_only = 0;
-                       break;
+
+                       if (!controller) {
+                               controller = strdup(token);
+                               if (controller == NULL)
+                                       break;
+                               strncpy(mount->name, controller, sizeof(mount->name));
+                       }
+
+                       if (strncmp(token, "nodev", strlen("nodev")) == 0) {
+                               *flags |= MS_NODEV;
+                       }
+                       if (strncmp(token, "noexec", strlen("noexec")) == 0) {
+                               *flags |= MS_NOEXEC;
+                       }
+                       if (strncmp(token, "nosuid", strlen("nosuid")) == 0) {
+                               *flags |= MS_NOSUID;
+                       }
+
+               } else if (!name_only) {
+                       /*
+                        * We have controller + name=, do the right thing, since
+                        * we are rebuuilding mount->name
+                        */
+                       strncat(mount->name, ",", FILENAME_MAX - strlen(mount->name)-1);
+                       strncat(mount->name, token,
+                                       FILENAME_MAX - strlen(mount->name) - 1);
                }
                token = strtok_r(NULL, ",", &save);
        }
 
+       free(controller);
        free(opts);
+
        if (name_only) {
                strncat(mount->name, ",", FILENAME_MAX - strlen(mount->name)-1);
                strncat(mount->name, "none",
@@ -667,6 +697,7 @@ static int cgroup_config_mount_fs(void)
        struct stat buff;
        int i;
        int error;
+       unsigned long flags;
 
        for (i = 0; i < config_table_index; i++) {
                struct cg_mount_table_s *curr = &(config_mount_table[i]);
@@ -698,12 +729,12 @@ static int cgroup_config_mount_fs(void)
                        goto out_err;
                }
 
-               error = cgroup_config_ajdust_mount_options(curr);
+               error = cgroup_config_ajdust_mount_options(curr, &flags);
                if (error)
                        goto out_err;
 
                ret = mount(CGROUP_FILESYSTEM, curr->mount.path,
-                               CGROUP_FILESYSTEM, 0, curr->name);
+                               CGROUP_FILESYSTEM, flags, curr->name);
 
                if (ret < 0) {
                        cgroup_err("Error: cannot mount %s to %s: %s\n",