// SPDX-License-Identifier: GPL-2.0
/*
* Linux Security Module infrastructure tests
* Tests for the lsm_list_modules system call
*
* Copyright © 2022 Casey Schaufler <[email protected]>
*/
#define _GNU_SOURCE
#include <linux/lsm.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include "../kselftest_harness.h"
#include "common.h"
TEST(size_null_lsm_list_modules)
{
const long page_size = sysconf(_SC_PAGESIZE);
__u64 *syscall_lsms = calloc(page_size, 1);
ASSERT_NE(NULL, syscall_lsms);
errno = 0;
ASSERT_EQ(-1, lsm_list_modules(syscall_lsms, NULL, 0));
ASSERT_EQ(EFAULT, errno);
free(syscall_lsms);
}
TEST(ids_null_lsm_list_modules)
{
const long page_size = sysconf(_SC_PAGESIZE);
__u32 size = page_size;
errno = 0;
ASSERT_EQ(-1, lsm_list_modules(NULL, &size, 0));
ASSERT_EQ(EFAULT, errno);
ASSERT_NE(1, size);
}
TEST(size_too_small_lsm_list_modules)
{
const long page_size = sysconf(_SC_PAGESIZE);
__u64 *syscall_lsms = calloc(page_size, 1);
__u32 size = 1;
ASSERT_NE(NULL, syscall_lsms);
errno = 0;
ASSERT_EQ(-1, lsm_list_modules(syscall_lsms, &size, 0));
ASSERT_EQ(E2BIG, errno);
ASSERT_NE(1, size);
free(syscall_lsms);
}
TEST(flags_set_lsm_list_modules)
{
const long page_size = sysconf(_SC_PAGESIZE);
__u64 *syscall_lsms = calloc(page_size, 1);
__u32 size = page_size;
ASSERT_NE(NULL, syscall_lsms);
errno = 0;
ASSERT_EQ(-1, lsm_list_modules(syscall_lsms, &size, 7));
ASSERT_EQ(EINVAL, errno);
ASSERT_EQ(page_size, size);
free(syscall_lsms);
}
TEST(correct_lsm_list_modules)
{
const long page_size = sysconf(_SC_PAGESIZE);
__u32 size = page_size;
__u64 *syscall_lsms = calloc(page_size, 1);
char *sysfs_lsms = calloc(page_size, 1);
char *name;
char *cp;
int count;
int i;
ASSERT_NE(NULL, sysfs_lsms);
ASSERT_NE(NULL, syscall_lsms);
ASSERT_EQ(0, read_sysfs_lsms(sysfs_lsms, page_size));
count = lsm_list_modules(syscall_lsms, &size, 0);
ASSERT_LE(1, count);
cp = sysfs_lsms;
for (i = 0; i < count; i++) {
switch (syscall_lsms[i]) {
case LSM_ID_CAPABILITY:
name = "capability";
break;
case LSM_ID_SELINUX:
name = "selinux";
break;
case LSM_ID_SMACK:
name = "smack";
break;
case LSM_ID_TOMOYO:
name = "tomoyo";
break;
case LSM_ID_APPARMOR:
name = "apparmor";
break;
case LSM_ID_YAMA:
name = "yama";
break;
case LSM_ID_LOADPIN:
name = "loadpin";
break;
case LSM_ID_SAFESETID:
name = "safesetid";
break;
case LSM_ID_LOCKDOWN:
name = "lockdown";
break;
case LSM_ID_BPF:
name = "bpf";
break;
case LSM_ID_LANDLOCK:
name = "landlock";
break;
case LSM_ID_IMA:
name = "ima";
break;
case LSM_ID_EVM:
name = "evm";
break;
case LSM_ID_IPE:
name = "ipe";
break;
default:
name = "INVALID";
break;
}
ASSERT_EQ(0, strncmp(cp, name, strlen(name)));
cp += strlen(name) + 1;
}
free(sysfs_lsms);
free(syscall_lsms);
}
TEST_HARNESS_MAIN