1*d3d929a8SCasey Schaufler // SPDX-License-Identifier: GPL-2.0
2*d3d929a8SCasey Schaufler /*
3*d3d929a8SCasey Schaufler * Linux Security Module infrastructure tests
4*d3d929a8SCasey Schaufler *
5*d3d929a8SCasey Schaufler * Copyright © 2023 Casey Schaufler <casey@schaufler-ca.com>
6*d3d929a8SCasey Schaufler */
7*d3d929a8SCasey Schaufler
8*d3d929a8SCasey Schaufler #define _GNU_SOURCE
9*d3d929a8SCasey Schaufler #include <linux/lsm.h>
10*d3d929a8SCasey Schaufler #include <fcntl.h>
11*d3d929a8SCasey Schaufler #include <string.h>
12*d3d929a8SCasey Schaufler #include <stdio.h>
13*d3d929a8SCasey Schaufler #include <stdlib.h>
14*d3d929a8SCasey Schaufler #include <unistd.h>
15*d3d929a8SCasey Schaufler #include <sys/types.h>
16*d3d929a8SCasey Schaufler #include "common.h"
17*d3d929a8SCasey Schaufler
18*d3d929a8SCasey Schaufler #define PROCATTR "/proc/self/attr/"
19*d3d929a8SCasey Schaufler
read_proc_attr(const char * attr,char * value,size_t size)20*d3d929a8SCasey Schaufler int read_proc_attr(const char *attr, char *value, size_t size)
21*d3d929a8SCasey Schaufler {
22*d3d929a8SCasey Schaufler int fd;
23*d3d929a8SCasey Schaufler int len;
24*d3d929a8SCasey Schaufler char *path;
25*d3d929a8SCasey Schaufler
26*d3d929a8SCasey Schaufler len = strlen(PROCATTR) + strlen(attr) + 1;
27*d3d929a8SCasey Schaufler path = calloc(len, 1);
28*d3d929a8SCasey Schaufler if (path == NULL)
29*d3d929a8SCasey Schaufler return -1;
30*d3d929a8SCasey Schaufler sprintf(path, "%s%s", PROCATTR, attr);
31*d3d929a8SCasey Schaufler
32*d3d929a8SCasey Schaufler fd = open(path, O_RDONLY);
33*d3d929a8SCasey Schaufler free(path);
34*d3d929a8SCasey Schaufler
35*d3d929a8SCasey Schaufler if (fd < 0)
36*d3d929a8SCasey Schaufler return -1;
37*d3d929a8SCasey Schaufler len = read(fd, value, size);
38*d3d929a8SCasey Schaufler
39*d3d929a8SCasey Schaufler close(fd);
40*d3d929a8SCasey Schaufler
41*d3d929a8SCasey Schaufler /* Ensure value is terminated */
42*d3d929a8SCasey Schaufler if (len <= 0 || len == size)
43*d3d929a8SCasey Schaufler return -1;
44*d3d929a8SCasey Schaufler value[len] = '\0';
45*d3d929a8SCasey Schaufler
46*d3d929a8SCasey Schaufler path = strchr(value, '\n');
47*d3d929a8SCasey Schaufler if (path)
48*d3d929a8SCasey Schaufler *path = '\0';
49*d3d929a8SCasey Schaufler
50*d3d929a8SCasey Schaufler return 0;
51*d3d929a8SCasey Schaufler }
52*d3d929a8SCasey Schaufler
read_sysfs_lsms(char * lsms,size_t size)53*d3d929a8SCasey Schaufler int read_sysfs_lsms(char *lsms, size_t size)
54*d3d929a8SCasey Schaufler {
55*d3d929a8SCasey Schaufler FILE *fp;
56*d3d929a8SCasey Schaufler size_t red;
57*d3d929a8SCasey Schaufler
58*d3d929a8SCasey Schaufler fp = fopen("/sys/kernel/security/lsm", "r");
59*d3d929a8SCasey Schaufler if (fp == NULL)
60*d3d929a8SCasey Schaufler return -1;
61*d3d929a8SCasey Schaufler red = fread(lsms, 1, size, fp);
62*d3d929a8SCasey Schaufler fclose(fp);
63*d3d929a8SCasey Schaufler
64*d3d929a8SCasey Schaufler if (red <= 0 || red == size)
65*d3d929a8SCasey Schaufler return -1;
66*d3d929a8SCasey Schaufler lsms[red] = '\0';
67*d3d929a8SCasey Schaufler return 0;
68*d3d929a8SCasey Schaufler }
69*d3d929a8SCasey Schaufler
attr_lsm_count(void)70*d3d929a8SCasey Schaufler int attr_lsm_count(void)
71*d3d929a8SCasey Schaufler {
72*d3d929a8SCasey Schaufler char *names = calloc(sysconf(_SC_PAGESIZE), 1);
73*d3d929a8SCasey Schaufler int count = 0;
74*d3d929a8SCasey Schaufler
75*d3d929a8SCasey Schaufler if (!names)
76*d3d929a8SCasey Schaufler return 0;
77*d3d929a8SCasey Schaufler
78*d3d929a8SCasey Schaufler if (read_sysfs_lsms(names, sysconf(_SC_PAGESIZE)))
79*d3d929a8SCasey Schaufler return 0;
80*d3d929a8SCasey Schaufler
81*d3d929a8SCasey Schaufler if (strstr(names, "selinux"))
82*d3d929a8SCasey Schaufler count++;
83*d3d929a8SCasey Schaufler if (strstr(names, "smack"))
84*d3d929a8SCasey Schaufler count++;
85*d3d929a8SCasey Schaufler if (strstr(names, "apparmor"))
86*d3d929a8SCasey Schaufler count++;
87*d3d929a8SCasey Schaufler
88*d3d929a8SCasey Schaufler return count;
89*d3d929a8SCasey Schaufler }
90