276 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Linux Security Module infrastructure tests4 * Tests for the lsm_get_self_attr system call5 *6 * Copyright © 2022 Casey Schaufler <casey@schaufler-ca.com>7 */8 9#define _GNU_SOURCE10#include <linux/lsm.h>11#include <fcntl.h>12#include <string.h>13#include <stdio.h>14#include <unistd.h>15#include <sys/types.h>16#include "../kselftest_harness.h"17#include "common.h"18 19static struct lsm_ctx *next_ctx(struct lsm_ctx *ctxp)20{21 void *vp;22 23 vp = (void *)ctxp + sizeof(*ctxp) + ctxp->ctx_len;24 return (struct lsm_ctx *)vp;25}26 27TEST(size_null_lsm_get_self_attr)28{29 const long page_size = sysconf(_SC_PAGESIZE);30 struct lsm_ctx *ctx = calloc(page_size, 1);31 32 ASSERT_NE(NULL, ctx);33 errno = 0;34 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, NULL, 0));35 ASSERT_EQ(EINVAL, errno);36 37 free(ctx);38}39 40TEST(ctx_null_lsm_get_self_attr)41{42 const long page_size = sysconf(_SC_PAGESIZE);43 __u32 size = page_size;44 int rc;45 46 rc = lsm_get_self_attr(LSM_ATTR_CURRENT, NULL, &size, 0);47 48 if (attr_lsm_count()) {49 ASSERT_NE(-1, rc);50 ASSERT_NE(1, size);51 } else {52 ASSERT_EQ(-1, rc);53 }54}55 56TEST(size_too_small_lsm_get_self_attr)57{58 const long page_size = sysconf(_SC_PAGESIZE);59 struct lsm_ctx *ctx = calloc(page_size, 1);60 __u32 size = 1;61 62 ASSERT_NE(NULL, ctx);63 errno = 0;64 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size, 0));65 if (attr_lsm_count()) {66 ASSERT_EQ(E2BIG, errno);67 } else {68 ASSERT_EQ(EOPNOTSUPP, errno);69 }70 ASSERT_NE(1, size);71 72 free(ctx);73}74 75TEST(flags_zero_lsm_get_self_attr)76{77 const long page_size = sysconf(_SC_PAGESIZE);78 struct lsm_ctx *ctx = calloc(page_size, 1);79 __u64 *syscall_lsms = calloc(page_size, 1);80 __u32 size;81 int lsmcount;82 int i;83 84 ASSERT_NE(NULL, ctx);85 errno = 0;86 size = page_size;87 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size,88 LSM_FLAG_SINGLE));89 ASSERT_EQ(EINVAL, errno);90 ASSERT_EQ(page_size, size);91 92 lsmcount = syscall(__NR_lsm_list_modules, syscall_lsms, &size, 0);93 ASSERT_LE(1, lsmcount);94 ASSERT_NE(NULL, syscall_lsms);95 96 for (i = 0; i < lsmcount; i++) {97 errno = 0;98 size = page_size;99 ctx->id = syscall_lsms[i];100 101 if (syscall_lsms[i] == LSM_ID_SELINUX ||102 syscall_lsms[i] == LSM_ID_SMACK ||103 syscall_lsms[i] == LSM_ID_APPARMOR) {104 ASSERT_EQ(1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx,105 &size, LSM_FLAG_SINGLE));106 } else {107 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx,108 &size,109 LSM_FLAG_SINGLE));110 }111 }112 113 free(ctx);114}115 116TEST(flags_overset_lsm_get_self_attr)117{118 const long page_size = sysconf(_SC_PAGESIZE);119 struct lsm_ctx *ctx = calloc(page_size, 1);120 __u32 size;121 122 ASSERT_NE(NULL, ctx);123 124 errno = 0;125 size = page_size;126 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT | LSM_ATTR_PREV, ctx,127 &size, 0));128 ASSERT_EQ(EOPNOTSUPP, errno);129 130 errno = 0;131 size = page_size;132 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size,133 LSM_FLAG_SINGLE |134 (LSM_FLAG_SINGLE << 1)));135 ASSERT_EQ(EINVAL, errno);136 137 free(ctx);138}139 140TEST(basic_lsm_get_self_attr)141{142 const long page_size = sysconf(_SC_PAGESIZE);143 __u32 size = page_size;144 struct lsm_ctx *ctx = calloc(page_size, 1);145 struct lsm_ctx *tctx = NULL;146 __u64 *syscall_lsms = calloc(page_size, 1);147 char *attr = calloc(page_size, 1);148 int cnt_current = 0;149 int cnt_exec = 0;150 int cnt_fscreate = 0;151 int cnt_keycreate = 0;152 int cnt_prev = 0;153 int cnt_sockcreate = 0;154 int lsmcount;155 int count;156 int i;157 158 ASSERT_NE(NULL, ctx);159 ASSERT_NE(NULL, syscall_lsms);160 161 lsmcount = syscall(__NR_lsm_list_modules, syscall_lsms, &size, 0);162 ASSERT_LE(1, lsmcount);163 164 for (i = 0; i < lsmcount; i++) {165 switch (syscall_lsms[i]) {166 case LSM_ID_SELINUX:167 cnt_current++;168 cnt_exec++;169 cnt_fscreate++;170 cnt_keycreate++;171 cnt_prev++;172 cnt_sockcreate++;173 break;174 case LSM_ID_SMACK:175 cnt_current++;176 break;177 case LSM_ID_APPARMOR:178 cnt_current++;179 cnt_exec++;180 cnt_prev++;181 break;182 default:183 break;184 }185 }186 187 if (cnt_current) {188 size = page_size;189 count = lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size, 0);190 ASSERT_EQ(cnt_current, count);191 tctx = ctx;192 ASSERT_EQ(0, read_proc_attr("current", attr, page_size));193 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));194 for (i = 1; i < count; i++) {195 tctx = next_ctx(tctx);196 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));197 }198 }199 if (cnt_exec) {200 size = page_size;201 count = lsm_get_self_attr(LSM_ATTR_EXEC, ctx, &size, 0);202 ASSERT_GE(cnt_exec, count);203 if (count > 0) {204 tctx = ctx;205 if (read_proc_attr("exec", attr, page_size) == 0)206 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));207 }208 for (i = 1; i < count; i++) {209 tctx = next_ctx(tctx);210 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));211 }212 }213 if (cnt_fscreate) {214 size = page_size;215 count = lsm_get_self_attr(LSM_ATTR_FSCREATE, ctx, &size, 0);216 ASSERT_GE(cnt_fscreate, count);217 if (count > 0) {218 tctx = ctx;219 if (read_proc_attr("fscreate", attr, page_size) == 0)220 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));221 }222 for (i = 1; i < count; i++) {223 tctx = next_ctx(tctx);224 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));225 }226 }227 if (cnt_keycreate) {228 size = page_size;229 count = lsm_get_self_attr(LSM_ATTR_KEYCREATE, ctx, &size, 0);230 ASSERT_GE(cnt_keycreate, count);231 if (count > 0) {232 tctx = ctx;233 if (read_proc_attr("keycreate", attr, page_size) == 0)234 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));235 }236 for (i = 1; i < count; i++) {237 tctx = next_ctx(tctx);238 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));239 }240 }241 if (cnt_prev) {242 size = page_size;243 count = lsm_get_self_attr(LSM_ATTR_PREV, ctx, &size, 0);244 ASSERT_GE(cnt_prev, count);245 if (count > 0) {246 tctx = ctx;247 ASSERT_EQ(0, read_proc_attr("prev", attr, page_size));248 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));249 for (i = 1; i < count; i++) {250 tctx = next_ctx(tctx);251 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));252 }253 }254 }255 if (cnt_sockcreate) {256 size = page_size;257 count = lsm_get_self_attr(LSM_ATTR_SOCKCREATE, ctx, &size, 0);258 ASSERT_GE(cnt_sockcreate, count);259 if (count > 0) {260 tctx = ctx;261 if (read_proc_attr("sockcreate", attr, page_size) == 0)262 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));263 }264 for (i = 1; i < count; i++) {265 tctx = next_ctx(tctx);266 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));267 }268 }269 270 free(ctx);271 free(attr);272 free(syscall_lsms);273}274 275TEST_HARNESS_MAIN276