Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Copyright (C) 2021 Microsoft Corporation
  4 *
  5 * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com)
  6 *
  7 * Measure critical data structures maintainted by SELinux
  8 * using IMA subsystem.
  9 */
 10#include <linux/vmalloc.h>
 11#include <linux/ima.h>
 12#include "security.h"
 13#include "ima.h"
 14
 15/*
 16 * selinux_ima_collect_state - Read selinux configuration settings
 17 *
 18 * @state: selinux_state
 19 *
 20 * On success returns the configuration settings string.
 21 * On error, returns NULL.
 22 */
 23static char *selinux_ima_collect_state(struct selinux_state *state)
 24{
 25	const char *on = "=1;", *off = "=0;";
 26	char *buf;
 27	int buf_len, len, i, rc;
 28
 29	buf_len = strlen("initialized=0;enforcing=0;checkreqprot=0;") + 1;
 30
 31	len = strlen(on);
 32	for (i = 0; i < __POLICYDB_CAP_MAX; i++)
 33		buf_len += strlen(selinux_policycap_names[i]) + len;
 34
 35	buf = kzalloc(buf_len, GFP_KERNEL);
 36	if (!buf)
 37		return NULL;
 38
 39	rc = strscpy(buf, "initialized", buf_len);
 40	WARN_ON(rc < 0);
 41
 42	rc = strlcat(buf, selinux_initialized(state) ? on : off, buf_len);
 43	WARN_ON(rc >= buf_len);
 44
 45	rc = strlcat(buf, "enforcing", buf_len);
 46	WARN_ON(rc >= buf_len);
 47
 48	rc = strlcat(buf, enforcing_enabled(state) ? on : off, buf_len);
 49	WARN_ON(rc >= buf_len);
 50
 51	rc = strlcat(buf, "checkreqprot", buf_len);
 52	WARN_ON(rc >= buf_len);
 53
 54	rc = strlcat(buf, checkreqprot_get(state) ? on : off, buf_len);
 55	WARN_ON(rc >= buf_len);
 56
 57	for (i = 0; i < __POLICYDB_CAP_MAX; i++) {
 58		rc = strlcat(buf, selinux_policycap_names[i], buf_len);
 59		WARN_ON(rc >= buf_len);
 60
 61		rc = strlcat(buf, state->policycap[i] ? on : off, buf_len);
 62		WARN_ON(rc >= buf_len);
 63	}
 64
 65	return buf;
 66}
 67
 68/*
 69 * selinux_ima_measure_state_locked - Measure SELinux state and hash of policy
 70 *
 71 * @state: selinux state struct
 72 */
 73void selinux_ima_measure_state_locked(struct selinux_state *state)
 74{
 75	char *state_str = NULL;
 76	void *policy = NULL;
 77	size_t policy_len;
 78	int rc = 0;
 79
 80	lockdep_assert_held(&state->policy_mutex);
 81
 82	state_str = selinux_ima_collect_state(state);
 83	if (!state_str) {
 84		pr_err("SELinux: %s: failed to read state.\n", __func__);
 85		return;
 86	}
 87
 88	ima_measure_critical_data("selinux", "selinux-state",
 89				  state_str, strlen(state_str), false,
 90				  NULL, 0);
 91
 92	kfree(state_str);
 93
 94	/*
 95	 * Measure SELinux policy only after initialization is completed.
 96	 */
 97	if (!selinux_initialized(state))
 98		return;
 99
100	rc = security_read_state_kernel(state, &policy, &policy_len);
101	if (rc) {
102		pr_err("SELinux: %s: failed to read policy %d.\n", __func__, rc);
103		return;
104	}
105
106	ima_measure_critical_data("selinux", "selinux-policy-hash",
107				  policy, policy_len, true,
108				  NULL, 0);
109
110	vfree(policy);
111}
112
113/*
114 * selinux_ima_measure_state - Measure SELinux state and hash of policy
115 *
116 * @state: selinux state struct
117 */
118void selinux_ima_measure_state(struct selinux_state *state)
119{
120	lockdep_assert_not_held(&state->policy_mutex);
121
122	mutex_lock(&state->policy_mutex);
123	selinux_ima_measure_state_locked(state);
124	mutex_unlock(&state->policy_mutex);
125}