From patchwork Sat Jun 13 02:41:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11602437 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C8020913 for ; Sat, 13 Jun 2020 02:41:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A6F84206A4 for ; Sat, 13 Jun 2020 02:41:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="o9UcLG+H" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726442AbgFMClh (ORCPT ); Fri, 12 Jun 2020 22:41:37 -0400 Received: from linux.microsoft.com ([13.77.154.182]:54102 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726396AbgFMClh (ORCPT ); Fri, 12 Jun 2020 22:41:37 -0400 Received: from localhost.localdomain (c-73-42-176-67.hsd1.wa.comcast.net [73.42.176.67]) by linux.microsoft.com (Postfix) with ESMTPSA id 28EFE20B4780; Fri, 12 Jun 2020 19:41:36 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 28EFE20B4780 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1592016096; bh=WVGmiiMS7vSH7gVwPrFMIQeJRoD4AACiFyCZE6Qm16s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o9UcLG+H6pVJ4Co/Cd/R0cdp/JBg2sTz6B5yOd2ll61VQR+dKb5917dnnhSQ28r35 mQXDPqaJBdWPYpg10rZwjlVuT9iOcjhux7ec2SA2Caz6ebauM5JVA7wfI3cSL9zPy6 GGb2EKm282FN2mZM6Vzbg5AcVWDhWkHg6rzQNt2w= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, stephen.smalley@gmail.com, casey@schaufler-ca.com Cc: jmorris@namei.org, linux-integrity@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/5] IMA: Add LSM_STATE func to measure LSM data Date: Fri, 12 Jun 2020 19:41:26 -0700 Message-Id: <20200613024130.3356-2-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200613024130.3356-1-nramas@linux.microsoft.com> References: <20200613024130.3356-1-nramas@linux.microsoft.com> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org Data provided by security modules need to be measured. A new IMA policy is required for handling this measurement. Define a new IMA policy func namely LSM_STATE to measure data provided by security modules. Update ima_match_rules() to check for LSM_STATE and ima_parse_rule() to handle LSM_STATE. Signed-off-by: Lakshmi Ramasubramanian --- Documentation/ABI/testing/ima_policy | 6 +++++- security/integrity/ima/ima.h | 1 + security/integrity/ima/ima_api.c | 2 +- security/integrity/ima/ima_policy.c | 28 +++++++++++++++++++++++----- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index cd572912c593..355bc3eade33 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -29,7 +29,7 @@ Description: base: func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK] [FIRMWARE_CHECK] [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK] - [KEXEC_CMDLINE] [KEY_CHECK] + [KEXEC_CMDLINE] [KEY_CHECK] [LSM_STATE] mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] [[^]MAY_EXEC] fsmagic:= hex value @@ -125,3 +125,7 @@ Description: keys added to .builtin_trusted_keys or .ima keyring: measure func=KEY_CHECK keyrings=.builtin_trusted_keys|.ima + + Example of measure rule using LSM_STATE to measure LSM data: + + measure func=LSM_STATE diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index df93ac258e01..58c62269028a 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -200,6 +200,7 @@ static inline unsigned int ima_hash_key(u8 *digest) hook(POLICY_CHECK) \ hook(KEXEC_CMDLINE) \ hook(KEY_CHECK) \ + hook(LSM_STATE) \ hook(MAX_CHECK) #define __ima_hook_enumify(ENUM) ENUM, diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index bf22de8b7ce0..0cebd2404dcf 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -176,7 +176,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, * subj=, obj=, type=, func=, mask=, fsmagic= * subj,obj, and type: are LSM specific. * func: FILE_CHECK | BPRM_CHECK | CREDS_CHECK | MMAP_CHECK | MODULE_CHECK - * | KEXEC_CMDLINE | KEY_CHECK + * | KEXEC_CMDLINE | KEY_CHECK | LSM_STATE * mask: contains the permission mask * fsmagic: hex value * diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index e493063a3c34..1a6ee09e6993 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -417,15 +417,31 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, const char *keyring) { int i; + int funcmatch = 0; - if ((func == KEXEC_CMDLINE) || (func == KEY_CHECK)) { + switch (func) { + case KEXEC_CMDLINE: + case KEY_CHECK: + case LSM_STATE: if ((rule->flags & IMA_FUNC) && (rule->func == func)) { if (func == KEY_CHECK) - return ima_match_keyring(rule, keyring, cred); - return true; - } - return false; + funcmatch = ima_match_keyring(rule, keyring, + cred) ? 1 : -1; + else + funcmatch = 1; + } else + funcmatch = -1; + + break; + + default: + funcmatch = 0; + break; } + + if (funcmatch) + return (funcmatch == 1) ? true : false; + if ((rule->flags & IMA_FUNC) && (rule->func != func && func != POST_SETATTR)) return false; @@ -1068,6 +1084,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) entry->func = KEXEC_CMDLINE; else if (strcmp(args[0].from, "KEY_CHECK") == 0) entry->func = KEY_CHECK; + else if (strcmp(args[0].from, "LSM_STATE") == 0) + entry->func = LSM_STATE; else result = -EINVAL; if (!result) From patchwork Sat Jun 13 02:41:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11602433 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8BCBC92A for ; Sat, 13 Jun 2020 02:41:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 681EB206A4 for ; Sat, 13 Jun 2020 02:41:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="TsbozQNP" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726404AbgFMClh (ORCPT ); Fri, 12 Jun 2020 22:41:37 -0400 Received: from linux.microsoft.com ([13.77.154.182]:54106 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726397AbgFMClh (ORCPT ); Fri, 12 Jun 2020 22:41:37 -0400 Received: from localhost.localdomain (c-73-42-176-67.hsd1.wa.comcast.net [73.42.176.67]) by linux.microsoft.com (Postfix) with ESMTPSA id 783EF20B4781; Fri, 12 Jun 2020 19:41:36 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 783EF20B4781 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1592016096; bh=h/7e7zImKiPAs9gLjjN0MWOthBgeaRk9JTCgA2PStTY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TsbozQNPeiFK7RNK/QjbJhy9+Sw4DCK3i1rNYqVyO9gH5Pnm/R+fiNzWpAZFesotY X0SJaSzez0aBKNTXipAEHX7UbI90sNLdSNcyTATW0PbizY75B2OvQZ48hnS1rPSPxp 3BAUF/TZdi39bQ9iR/Tb0Oy+nVS0LMIjDcjD0nMo= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, stephen.smalley@gmail.com, casey@schaufler-ca.com Cc: jmorris@namei.org, linux-integrity@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/5] IMA: Define an IMA hook to measure LSM data Date: Fri, 12 Jun 2020 19:41:27 -0700 Message-Id: <20200613024130.3356-3-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200613024130.3356-1-nramas@linux.microsoft.com> References: <20200613024130.3356-1-nramas@linux.microsoft.com> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org LSM requires an IMA hook to be defined by the IMA subsystem to measure the data gathered from the security modules. Define a new IMA hook, namely ima_lsm_state(), that the LSM will call to measure the data gathered from the security modules. Sample IMA log entry for LSM measurement: 10 47eed9... ima-buf sha256:402f6b... lsm-state:selinux 656e61626c65643d313b656e666f7263696e673d30 Signed-off-by: Lakshmi Ramasubramanian --- include/linux/ima.h | 4 ++++ security/integrity/ima/ima_main.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/linux/ima.h b/include/linux/ima.h index 9164e1534ec9..56681a648b3d 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -26,6 +26,7 @@ extern int ima_post_read_file(struct file *file, void *buf, loff_t size, extern void ima_post_path_mknod(struct dentry *dentry); extern int ima_file_hash(struct file *file, char *buf, size_t buf_size); extern void ima_kexec_cmdline(const void *buf, int size); +extern void ima_lsm_state(const char *lsm_name, const void *buf, int size); #ifdef CONFIG_IMA_KEXEC extern void ima_add_kexec_buffer(struct kimage *image); @@ -104,6 +105,9 @@ static inline int ima_file_hash(struct file *file, char *buf, size_t buf_size) } static inline void ima_kexec_cmdline(const void *buf, int size) {} + +static inline void ima_lsm_state(const char *lsm_name, + const void *buf, int size) {} #endif /* CONFIG_IMA */ #ifndef CONFIG_IMA_KEXEC diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index c1583d98c5e5..34be962054fb 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -827,6 +827,36 @@ void ima_kexec_cmdline(const void *buf, int size) KEXEC_CMDLINE, 0, NULL); } +/** + * ima_lsm_state - measure LSM specific state + * @lsm_name: Name of the LSM + * @buf: pointer to buffer containing LSM specific state + * @size: Number of bytes in buf + * + * Buffers can only be measured, not appraised. + */ +void ima_lsm_state(const char *lsm_name, const void *buf, int size) +{ + const char *eventname = "lsm-state:"; + char *lsmstatestring; + int lsmstatelen; + + if (!lsm_name || !buf || !size) + return; + + lsmstatelen = strlen(eventname) + strlen(lsm_name) + 1; + lsmstatestring = kzalloc(lsmstatelen, GFP_KERNEL); + if (!lsmstatestring) + return; + + strcpy(lsmstatestring, eventname); + strcat(lsmstatestring, lsm_name); + + process_buffer_measurement(buf, size, lsmstatestring, + LSM_STATE, 0, NULL); + kfree(lsmstatestring); +} + static int __init init_ima(void) { int error; From patchwork Sat Jun 13 02:41:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11602455 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CC11D913 for ; Sat, 13 Jun 2020 02:42:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B290F206A4 for ; Sat, 13 Jun 2020 02:42:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="m2gr/iG2" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726445AbgFMCl6 (ORCPT ); Fri, 12 Jun 2020 22:41:58 -0400 Received: from linux.microsoft.com ([13.77.154.182]:54118 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726398AbgFMClh (ORCPT ); Fri, 12 Jun 2020 22:41:37 -0400 Received: from localhost.localdomain (c-73-42-176-67.hsd1.wa.comcast.net [73.42.176.67]) by linux.microsoft.com (Postfix) with ESMTPSA id C47BB20B4782; Fri, 12 Jun 2020 19:41:36 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com C47BB20B4782 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1592016097; bh=F0KUrRtb3r8N9EtpYLjSg6CNnVGLSPMem/gwYtUR/WI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=m2gr/iG2sDvLPc/au9Hl+dRZpsiOGNRoPgChg3DgH5M9LMgbYfilZPeZEcM4JpVZ6 /iz8aU+FgTF+u7tCebedOxCYTqJJtxLshjrkxpKEJ0TPmw0xae3bllzXw2gHUG9xKM uGAJ7iahyFf+mawyGmdkyNeaPH9Bo/2RK5mRSF+0= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, stephen.smalley@gmail.com, casey@schaufler-ca.com Cc: jmorris@namei.org, linux-integrity@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/5] LSM: Add security_state function pointer in lsm_info struct Date: Fri, 12 Jun 2020 19:41:28 -0700 Message-Id: <20200613024130.3356-4-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200613024130.3356-1-nramas@linux.microsoft.com> References: <20200613024130.3356-1-nramas@linux.microsoft.com> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The security modules that require their data to be measured need to define a function that the LSM can call to gather the data. Add a function pointer field namely security_state in lsm_info structure. Update LSM to call this security module function, if defined, to gather data and measure it by calling the IMA hook ima_lsm_state(). Signed-off-by: Lakshmi Ramasubramanian --- include/linux/lsm_hooks.h | 2 ++ security/security.c | 60 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 3e62dab77699..da248c3fd4ac 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1568,6 +1568,8 @@ struct lsm_info { int *enabled; /* Optional: controlled by CONFIG_LSM */ int (*init)(void); /* Required. */ struct lsm_blob_sizes *blobs; /* Optional: for blob sharing. */ + int (*security_state)(char **lsm_name, void **state, + int *state_len); /*Optional */ }; extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; diff --git a/security/security.c b/security/security.c index e0290b7e6a08..a6e2d1cd95af 100644 --- a/security/security.c +++ b/security/security.c @@ -86,6 +86,9 @@ static __initconst const char * const builtin_lsm_order = CONFIG_LSM; static __initdata struct lsm_info **ordered_lsms; static __initdata struct lsm_info *exclusive; +static struct lsm_info *security_state_lsms; +static int security_state_lsms_count; + static __initdata bool debug; #define init_debug(...) \ do { \ @@ -235,6 +238,57 @@ static void __init initialize_lsm(struct lsm_info *lsm) } } +static int measure_security_state(struct lsm_info *lsm) +{ + char *lsm_name = NULL; + void *state = NULL; + int state_len = 0; + int rc; + + if (!lsm->security_state) + return 0; + + rc = lsm->security_state(&lsm_name, &state, &state_len); + if ((rc == 0) && (state_len > 0)) { + ima_lsm_state(lsm_name, state, state_len); + kfree(state); + kfree(lsm_name); + } + + return rc; +} + +static void __init initialize_security_state_lsms(void) +{ + struct lsm_info **lsm; + int count = 0; + int inx; + + for (lsm = ordered_lsms; *lsm; lsm++) { + if ((*lsm)->security_state) + count++; + } + + if (count == 0) + return; + + security_state_lsms = kcalloc(count, sizeof(struct lsm_info), + GFP_KERNEL); + if (!security_state_lsms) + return; + + inx = 0; + for (lsm = ordered_lsms; *lsm; lsm++) { + if ((*lsm)->security_state) { + security_state_lsms[inx].security_state = + (*lsm)->security_state; + inx++; + } + } + + security_state_lsms_count = count; +} + /* Populate ordered LSMs list from comma-separated LSM name list. */ static void __init ordered_lsm_parse(const char *order, const char *origin) { @@ -352,8 +406,12 @@ static void __init ordered_lsm_init(void) lsm_early_cred((struct cred *) current->cred); lsm_early_task(current); - for (lsm = ordered_lsms; *lsm; lsm++) + for (lsm = ordered_lsms; *lsm; lsm++) { initialize_lsm(*lsm); + measure_security_state(*lsm); + } + + initialize_security_state_lsms(); kfree(ordered_lsms); } From patchwork Sat Jun 13 02:41:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11602449 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 75D25913 for ; Sat, 13 Jun 2020 02:41:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5A46F2074B for ; Sat, 13 Jun 2020 02:41:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="SI8Fof/0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726290AbgFMClp (ORCPT ); Fri, 12 Jun 2020 22:41:45 -0400 Received: from linux.microsoft.com ([13.77.154.182]:54148 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726401AbgFMCli (ORCPT ); Fri, 12 Jun 2020 22:41:38 -0400 Received: from localhost.localdomain (c-73-42-176-67.hsd1.wa.comcast.net [73.42.176.67]) by linux.microsoft.com (Postfix) with ESMTPSA id 1B5AA20B4783; Fri, 12 Jun 2020 19:41:37 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 1B5AA20B4783 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1592016097; bh=9/oXutbjuzQ/I6R6w3F6z0lqsxijqgXEqgpbX21P2Gg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SI8Fof/01+jriFe6mbCZvsCy7DRxgq0daX7KNERJA0B7gG8NkhFxziMU1CQDJs8L+ Nwt+Vxz+YqUrlJcAOj9IE8pmD5AsR1FpNPHiGBuXBukB3rKJRMPc9sjh5krlzp7Z0i dPzpW8tS88pVhO90ZbSLIDX0WQnJfrGKHqzFsy1w= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, stephen.smalley@gmail.com, casey@schaufler-ca.com Cc: jmorris@namei.org, linux-integrity@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/5] LSM: Define SELinux function to measure security state Date: Fri, 12 Jun 2020 19:41:29 -0700 Message-Id: <20200613024130.3356-5-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200613024130.3356-1-nramas@linux.microsoft.com> References: <20200613024130.3356-1-nramas@linux.microsoft.com> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org SELinux needs to implement the interface function, security_state(), for the LSM to gather SELinux data for measuring. Define the security_state() function in SELinux. The security modules should be able to notify the LSM when there is a change in the module's data. Define a function namely security_state_change() in the LSM that the security modules can call to provide the updated data for measurement. Call security_state_change() function from SELinux to report data when SELinux's state is updated. Signed-off-by: Lakshmi Ramasubramanian --- include/linux/lsm_hooks.h | 3 ++ security/security.c | 5 ++++ security/selinux/hooks.c | 43 +++++++++++++++++++++++++++++ security/selinux/include/security.h | 2 ++ security/selinux/selinuxfs.c | 1 + 5 files changed, 54 insertions(+) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index da248c3fd4ac..a63de046139e 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1572,6 +1572,9 @@ struct lsm_info { int *state_len); /*Optional */ }; +/* Called by LSMs to notify security state change */ +extern void security_state_change(char *lsm_name, void *state, int state_len); + extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[]; diff --git a/security/security.c b/security/security.c index a6e2d1cd95af..e7175db5a093 100644 --- a/security/security.c +++ b/security/security.c @@ -238,6 +238,11 @@ static void __init initialize_lsm(struct lsm_info *lsm) } } +void security_state_change(char *lsm_name, void *state, int state_len) +{ + ima_lsm_state(lsm_name, state, state_len); +} + static int measure_security_state(struct lsm_info *lsm) { char *lsm_name = NULL; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7e954b555be6..bbc908a1fcd1 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7225,6 +7225,47 @@ static __init int selinux_init(void) return 0; } +static int selinux_security_state(char **lsm_name, void **state, + int *state_len) +{ + int rc = 0; + char *new_state; + static char *security_state_string = "enabled=%d;enforcing=%d"; + + *lsm_name = kstrdup("selinux", GFP_KERNEL); + if (!*lsm_name) + return -ENOMEM; + + new_state = kzalloc(strlen(security_state_string) + 1, GFP_KERNEL); + if (!new_state) { + kfree(*lsm_name); + *lsm_name = NULL; + rc = -ENOMEM; + goto out; + } + + *state_len = sprintf(new_state, security_state_string, + !selinux_disabled(&selinux_state), + enforcing_enabled(&selinux_state)); + *state = new_state; + +out: + return rc; +} + +void notify_security_state_change(void) +{ + char *lsm_name = NULL; + void *state = NULL; + int state_len = 0; + + if (!selinux_security_state(&lsm_name, &state, &state_len)) { + security_state_change(lsm_name, state, state_len); + kfree(state); + kfree(lsm_name); + } +} + static void delayed_superblock_init(struct super_block *sb, void *unused) { selinux_set_mnt_opts(sb, NULL, 0, NULL); @@ -7247,6 +7288,7 @@ DEFINE_LSM(selinux) = { .enabled = &selinux_enabled_boot, .blobs = &selinux_blob_sizes, .init = selinux_init, + .security_state = selinux_security_state, }; #if defined(CONFIG_NETFILTER) @@ -7357,6 +7399,7 @@ int selinux_disable(struct selinux_state *state) } selinux_mark_disabled(state); + notify_security_state_change(); pr_info("SELinux: Disabled at runtime.\n"); diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index b0e02cfe3ce1..83c6ada45c7c 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -232,6 +232,8 @@ size_t security_policydb_len(struct selinux_state *state); int security_policycap_supported(struct selinux_state *state, unsigned int req_cap); +void notify_security_state_change(void); + #define SEL_VEC_MAX 32 struct av_decision { u32 allowed; diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 4781314c2510..8a5ba32a7775 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -173,6 +173,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, from_kuid(&init_user_ns, audit_get_loginuid(current)), audit_get_sessionid(current)); enforcing_set(state, new_value); + notify_security_state_change(); if (new_value) avc_ss_reset(state->avc, 0); selnl_notify_setenforce(new_value); From patchwork Sat Jun 13 02:41:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11602443 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8D1EA92A for ; Sat, 13 Jun 2020 02:41:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 728582074B for ; Sat, 13 Jun 2020 02:41:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="kEtciZBn" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726502AbgFMClq (ORCPT ); Fri, 12 Jun 2020 22:41:46 -0400 Received: from linux.microsoft.com ([13.77.154.182]:54150 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726441AbgFMCli (ORCPT ); Fri, 12 Jun 2020 22:41:38 -0400 Received: from localhost.localdomain (c-73-42-176-67.hsd1.wa.comcast.net [73.42.176.67]) by linux.microsoft.com (Postfix) with ESMTPSA id 6D1A520B4785; Fri, 12 Jun 2020 19:41:37 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 6D1A520B4785 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1592016097; bh=bNdc4U/VTJDtcRp/g3v1Y+eSv6Ss10i7Sm+a4SYsn4Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kEtciZBnky8xzcdy61W0t1oH+SEDvfREdGt3kfQ5zWK7WGhu6dkMtNAfzwC6IRtIC HmYSP+GUITWFKpb3NuY7oh5LOnsrVg6G4d/N0qVrowJd0WC7LKgM6CDlbHttv7QF5B 36jXNaGkAkwnbc2kC9HIUzluKrVLNK5TjMM6jDYc= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, stephen.smalley@gmail.com, casey@schaufler-ca.com Cc: jmorris@namei.org, linux-integrity@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 5/5] LSM: Define workqueue for measuring security module state Date: Fri, 12 Jun 2020 19:41:30 -0700 Message-Id: <20200613024130.3356-6-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200613024130.3356-1-nramas@linux.microsoft.com> References: <20200613024130.3356-1-nramas@linux.microsoft.com> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The data maintained by the security modules could be tampered with by malware. The LSM needs to periodically query the state of the security modules and measure the data when the state is changed. Define a workqueue for handling this periodic query and measurement. Signed-off-by: Lakshmi Ramasubramanian --- security/security.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/security/security.c b/security/security.c index e7175db5a093..3dad6766cb9d 100644 --- a/security/security.c +++ b/security/security.c @@ -89,6 +89,11 @@ static __initdata struct lsm_info *exclusive; static struct lsm_info *security_state_lsms; static int security_state_lsms_count; +static long security_state_timeout = 300000; /* 5 Minutes */ +static void security_state_handler(struct work_struct *work); +static DECLARE_DELAYED_WORK(security_state_delayed_work, + security_state_handler); + static __initdata bool debug; #define init_debug(...) \ do { \ @@ -294,6 +299,26 @@ static void __init initialize_security_state_lsms(void) security_state_lsms_count = count; } +static void initialize_security_state_monitor(void) +{ + if (security_state_lsms_count == 0) + return; + + schedule_delayed_work(&security_state_delayed_work, + msecs_to_jiffies(security_state_timeout)); +} + +static void security_state_handler(struct work_struct *work) +{ + int inx; + + for (inx = 0; inx < security_state_lsms_count; inx++) + measure_security_state(&(security_state_lsms[inx])); + + schedule_delayed_work(&security_state_delayed_work, + msecs_to_jiffies(security_state_timeout)); +} + /* Populate ordered LSMs list from comma-separated LSM name list. */ static void __init ordered_lsm_parse(const char *order, const char *origin) { @@ -417,6 +442,7 @@ static void __init ordered_lsm_init(void) } initialize_security_state_lsms(); + initialize_security_state_monitor(); kfree(ordered_lsms); }