cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cgroup.c (2078B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <linux/stringify.h>
      3#include <sys/types.h>
      4#include <sys/stat.h>
      5#include <fcntl.h>
      6#include <stdio.h>
      7#include <stdlib.h>
      8#include <string.h>
      9#include "fs.h"
     10
     11struct cgroupfs_cache_entry {
     12	char	subsys[32];
     13	char	mountpoint[PATH_MAX];
     14};
     15
     16/* just cache last used one */
     17static struct cgroupfs_cache_entry cached;
     18
     19int cgroupfs_find_mountpoint(char *buf, size_t maxlen, const char *subsys)
     20{
     21	FILE *fp;
     22	char *line = NULL;
     23	size_t len = 0;
     24	char *p, *path;
     25	char mountpoint[PATH_MAX];
     26
     27	if (!strcmp(cached.subsys, subsys)) {
     28		if (strlen(cached.mountpoint) < maxlen) {
     29			strcpy(buf, cached.mountpoint);
     30			return 0;
     31		}
     32		return -1;
     33	}
     34
     35	fp = fopen("/proc/mounts", "r");
     36	if (!fp)
     37		return -1;
     38
     39	/*
     40	 * in order to handle split hierarchy, we need to scan /proc/mounts
     41	 * and inspect every cgroupfs mount point to find one that has
     42	 * the given subsystem.  If we found v1, just use it.  If not we can
     43	 * use v2 path as a fallback.
     44	 */
     45	mountpoint[0] = '\0';
     46
     47	/*
     48	 * The /proc/mounts has the follow format:
     49	 *
     50	 *   <devname> <mount point> <fs type> <options> ...
     51	 *
     52	 */
     53	while (getline(&line, &len, fp) != -1) {
     54		/* skip devname */
     55		p = strchr(line, ' ');
     56		if (p == NULL)
     57			continue;
     58
     59		/* save the mount point */
     60		path = ++p;
     61		p = strchr(p, ' ');
     62		if (p == NULL)
     63			continue;
     64
     65		*p++ = '\0';
     66
     67		/* check filesystem type */
     68		if (strncmp(p, "cgroup", 6))
     69			continue;
     70
     71		if (p[6] == '2') {
     72			/* save cgroup v2 path */
     73			strcpy(mountpoint, path);
     74			continue;
     75		}
     76
     77		/* now we have cgroup v1, check the options for subsystem */
     78		p += 7;
     79
     80		p = strstr(p, subsys);
     81		if (p == NULL)
     82			continue;
     83
     84		/* sanity check: it should be separated by a space or a comma */
     85		if (!strchr(" ,", p[-1]) || !strchr(" ,", p[strlen(subsys)]))
     86			continue;
     87
     88		strcpy(mountpoint, path);
     89		break;
     90	}
     91	free(line);
     92	fclose(fp);
     93
     94	strncpy(cached.subsys, subsys, sizeof(cached.subsys) - 1);
     95	strcpy(cached.mountpoint, mountpoint);
     96
     97	if (mountpoint[0] && strlen(mountpoint) < maxlen) {
     98		strcpy(buf, mountpoint);
     99		return 0;
    100	}
    101	return -1;
    102}