mirror of
https://github.com/torvalds/linux.git
synced 2024-12-05 18:41:23 +00:00
a5a858f622
Change the size parameters in lsm_list_modules(), lsm_set_self_attr() and lsm_get_self_attr() from size_t to u32. This avoids the need to have different interfaces for 32 and 64 bit systems. Cc: stable@vger.kernel.org Fixes:a04a119808
("LSM: syscalls for current process attributes") Fixes:ad4aff9ec2
("LSM: Create lsm_list_modules system call") Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Reported-and-reviewed-by: Dmitry V. Levin <ldv@strace.io> [PM: subject and metadata tweaks, syscall.h fixes] Signed-off-by: Paul Moore <paul@paul-moore.com>
276 lines
6.2 KiB
C
276 lines
6.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Linux Security Module infrastructure tests
|
|
* Tests for the lsm_get_self_attr system call
|
|
*
|
|
* Copyright © 2022 Casey Schaufler <casey@schaufler-ca.com>
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
#include <linux/lsm.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include "../kselftest_harness.h"
|
|
#include "common.h"
|
|
|
|
static struct lsm_ctx *next_ctx(struct lsm_ctx *ctxp)
|
|
{
|
|
void *vp;
|
|
|
|
vp = (void *)ctxp + sizeof(*ctxp) + ctxp->ctx_len;
|
|
return (struct lsm_ctx *)vp;
|
|
}
|
|
|
|
TEST(size_null_lsm_get_self_attr)
|
|
{
|
|
const long page_size = sysconf(_SC_PAGESIZE);
|
|
struct lsm_ctx *ctx = calloc(page_size, 1);
|
|
|
|
ASSERT_NE(NULL, ctx);
|
|
errno = 0;
|
|
ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, NULL, 0));
|
|
ASSERT_EQ(EINVAL, errno);
|
|
|
|
free(ctx);
|
|
}
|
|
|
|
TEST(ctx_null_lsm_get_self_attr)
|
|
{
|
|
const long page_size = sysconf(_SC_PAGESIZE);
|
|
__u32 size = page_size;
|
|
int rc;
|
|
|
|
rc = lsm_get_self_attr(LSM_ATTR_CURRENT, NULL, &size, 0);
|
|
|
|
if (attr_lsm_count()) {
|
|
ASSERT_NE(-1, rc);
|
|
ASSERT_NE(1, size);
|
|
} else {
|
|
ASSERT_EQ(-1, rc);
|
|
}
|
|
}
|
|
|
|
TEST(size_too_small_lsm_get_self_attr)
|
|
{
|
|
const long page_size = sysconf(_SC_PAGESIZE);
|
|
struct lsm_ctx *ctx = calloc(page_size, 1);
|
|
__u32 size = 1;
|
|
|
|
ASSERT_NE(NULL, ctx);
|
|
errno = 0;
|
|
ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size, 0));
|
|
if (attr_lsm_count()) {
|
|
ASSERT_EQ(E2BIG, errno);
|
|
} else {
|
|
ASSERT_EQ(EOPNOTSUPP, errno);
|
|
}
|
|
ASSERT_NE(1, size);
|
|
|
|
free(ctx);
|
|
}
|
|
|
|
TEST(flags_zero_lsm_get_self_attr)
|
|
{
|
|
const long page_size = sysconf(_SC_PAGESIZE);
|
|
struct lsm_ctx *ctx = calloc(page_size, 1);
|
|
__u64 *syscall_lsms = calloc(page_size, 1);
|
|
__u32 size;
|
|
int lsmcount;
|
|
int i;
|
|
|
|
ASSERT_NE(NULL, ctx);
|
|
errno = 0;
|
|
size = page_size;
|
|
ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size,
|
|
LSM_FLAG_SINGLE));
|
|
ASSERT_EQ(EINVAL, errno);
|
|
ASSERT_EQ(page_size, size);
|
|
|
|
lsmcount = syscall(__NR_lsm_list_modules, syscall_lsms, &size, 0);
|
|
ASSERT_LE(1, lsmcount);
|
|
ASSERT_NE(NULL, syscall_lsms);
|
|
|
|
for (i = 0; i < lsmcount; i++) {
|
|
errno = 0;
|
|
size = page_size;
|
|
ctx->id = syscall_lsms[i];
|
|
|
|
if (syscall_lsms[i] == LSM_ID_SELINUX ||
|
|
syscall_lsms[i] == LSM_ID_SMACK ||
|
|
syscall_lsms[i] == LSM_ID_APPARMOR) {
|
|
ASSERT_EQ(1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx,
|
|
&size, LSM_FLAG_SINGLE));
|
|
} else {
|
|
ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx,
|
|
&size,
|
|
LSM_FLAG_SINGLE));
|
|
}
|
|
}
|
|
|
|
free(ctx);
|
|
}
|
|
|
|
TEST(flags_overset_lsm_get_self_attr)
|
|
{
|
|
const long page_size = sysconf(_SC_PAGESIZE);
|
|
struct lsm_ctx *ctx = calloc(page_size, 1);
|
|
__u32 size;
|
|
|
|
ASSERT_NE(NULL, ctx);
|
|
|
|
errno = 0;
|
|
size = page_size;
|
|
ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT | LSM_ATTR_PREV, ctx,
|
|
&size, 0));
|
|
ASSERT_EQ(EOPNOTSUPP, errno);
|
|
|
|
errno = 0;
|
|
size = page_size;
|
|
ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size,
|
|
LSM_FLAG_SINGLE |
|
|
(LSM_FLAG_SINGLE << 1)));
|
|
ASSERT_EQ(EINVAL, errno);
|
|
|
|
free(ctx);
|
|
}
|
|
|
|
TEST(basic_lsm_get_self_attr)
|
|
{
|
|
const long page_size = sysconf(_SC_PAGESIZE);
|
|
__u32 size = page_size;
|
|
struct lsm_ctx *ctx = calloc(page_size, 1);
|
|
struct lsm_ctx *tctx = NULL;
|
|
__u64 *syscall_lsms = calloc(page_size, 1);
|
|
char *attr = calloc(page_size, 1);
|
|
int cnt_current = 0;
|
|
int cnt_exec = 0;
|
|
int cnt_fscreate = 0;
|
|
int cnt_keycreate = 0;
|
|
int cnt_prev = 0;
|
|
int cnt_sockcreate = 0;
|
|
int lsmcount;
|
|
int count;
|
|
int i;
|
|
|
|
ASSERT_NE(NULL, ctx);
|
|
ASSERT_NE(NULL, syscall_lsms);
|
|
|
|
lsmcount = syscall(__NR_lsm_list_modules, syscall_lsms, &size, 0);
|
|
ASSERT_LE(1, lsmcount);
|
|
|
|
for (i = 0; i < lsmcount; i++) {
|
|
switch (syscall_lsms[i]) {
|
|
case LSM_ID_SELINUX:
|
|
cnt_current++;
|
|
cnt_exec++;
|
|
cnt_fscreate++;
|
|
cnt_keycreate++;
|
|
cnt_prev++;
|
|
cnt_sockcreate++;
|
|
break;
|
|
case LSM_ID_SMACK:
|
|
cnt_current++;
|
|
break;
|
|
case LSM_ID_APPARMOR:
|
|
cnt_current++;
|
|
cnt_exec++;
|
|
cnt_prev++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (cnt_current) {
|
|
size = page_size;
|
|
count = lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size, 0);
|
|
ASSERT_EQ(cnt_current, count);
|
|
tctx = ctx;
|
|
ASSERT_EQ(0, read_proc_attr("current", attr, page_size));
|
|
ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
|
|
for (i = 1; i < count; i++) {
|
|
tctx = next_ctx(tctx);
|
|
ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
|
|
}
|
|
}
|
|
if (cnt_exec) {
|
|
size = page_size;
|
|
count = lsm_get_self_attr(LSM_ATTR_EXEC, ctx, &size, 0);
|
|
ASSERT_GE(cnt_exec, count);
|
|
if (count > 0) {
|
|
tctx = ctx;
|
|
if (read_proc_attr("exec", attr, page_size) == 0)
|
|
ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
|
|
}
|
|
for (i = 1; i < count; i++) {
|
|
tctx = next_ctx(tctx);
|
|
ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
|
|
}
|
|
}
|
|
if (cnt_fscreate) {
|
|
size = page_size;
|
|
count = lsm_get_self_attr(LSM_ATTR_FSCREATE, ctx, &size, 0);
|
|
ASSERT_GE(cnt_fscreate, count);
|
|
if (count > 0) {
|
|
tctx = ctx;
|
|
if (read_proc_attr("fscreate", attr, page_size) == 0)
|
|
ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
|
|
}
|
|
for (i = 1; i < count; i++) {
|
|
tctx = next_ctx(tctx);
|
|
ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
|
|
}
|
|
}
|
|
if (cnt_keycreate) {
|
|
size = page_size;
|
|
count = lsm_get_self_attr(LSM_ATTR_KEYCREATE, ctx, &size, 0);
|
|
ASSERT_GE(cnt_keycreate, count);
|
|
if (count > 0) {
|
|
tctx = ctx;
|
|
if (read_proc_attr("keycreate", attr, page_size) == 0)
|
|
ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
|
|
}
|
|
for (i = 1; i < count; i++) {
|
|
tctx = next_ctx(tctx);
|
|
ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
|
|
}
|
|
}
|
|
if (cnt_prev) {
|
|
size = page_size;
|
|
count = lsm_get_self_attr(LSM_ATTR_PREV, ctx, &size, 0);
|
|
ASSERT_GE(cnt_prev, count);
|
|
if (count > 0) {
|
|
tctx = ctx;
|
|
ASSERT_EQ(0, read_proc_attr("prev", attr, page_size));
|
|
ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
|
|
for (i = 1; i < count; i++) {
|
|
tctx = next_ctx(tctx);
|
|
ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
|
|
}
|
|
}
|
|
}
|
|
if (cnt_sockcreate) {
|
|
size = page_size;
|
|
count = lsm_get_self_attr(LSM_ATTR_SOCKCREATE, ctx, &size, 0);
|
|
ASSERT_GE(cnt_sockcreate, count);
|
|
if (count > 0) {
|
|
tctx = ctx;
|
|
if (read_proc_attr("sockcreate", attr, page_size) == 0)
|
|
ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
|
|
}
|
|
for (i = 1; i < count; i++) {
|
|
tctx = next_ctx(tctx);
|
|
ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
|
|
}
|
|
}
|
|
|
|
free(ctx);
|
|
free(attr);
|
|
free(syscall_lsms);
|
|
}
|
|
|
|
TEST_HARNESS_MAIN
|