Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp138320ybg; Tue, 22 Oct 2019 17:34:35 -0700 (PDT) X-Google-Smtp-Source: APXvYqx2tiecCj91SqkK5bmTdQzOB2BqMBsOJtu+w06NRscCacGe0ZwNX9cY7bc1FzILqlMCHJeP X-Received: by 2002:a17:906:a986:: with SMTP id jr6mr29874527ejb.158.1571790875109; Tue, 22 Oct 2019 17:34:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571790875; cv=none; d=google.com; s=arc-20160816; b=KafkadGL2zyk+dMx5Xsb2z/kevALS4Jp86tU+xndwlmLyHCwjKQ0WgeFEvcY4T2Dcl QeWJHadqltnc5gePA/cPikR/DTdGkoB4J5j8fcTSk6v5CxqOwCH1bPGxIspV0yM2HsI9 HwHhPbyZDP7cPY5Dq430NT0CwDYDGEDDPQIvkmTM5D0yMU7/LZQR4XbIL94WQVTiFkQi YcNWqjjVrmW35CzmHUmeY5EsoRTkj3x8IrhGE2WAg7lMHQRV/R1wH0H0dZ1Byn6b5Ijc XlQuPYgWSG1KwpjNPkThDE7L12YMRd9C+s5UlNhowCbCV2ylWOLmmPA5z340iBA7NPiX kVoA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:dkim-filter; bh=l3/xpxDJDNPHhTjWJ68OgeQThxUX96N97fTeydZwHaM=; b=OOJQW7OcUoGCobZRezaRgHFA0eMLdDEyuzS4Jb8dVturl7eU9uiQMrf/iA7ubUANOu K7Q46/tMhntGAEF+o2aqFgJrthf5Xn1SaO2Zg4Dy7cLb+pTuP6OIsBnDUNktEZssoZzh ZIPmd53zILic3HlOKhsL97i8z5qCVC8NpCznsLwpwUE7yJ8sI7zt5b5U9MOvhO3DXz69 K3j0bPypqcSJScq7v4aCB/ytEAQpbs1NF90AApgwWNjItJph+MylEwjOIBMCXMKZw2f8 teWBad8+nDIKeLCAK4/MCWk6MEv7abeYCc0Vzju4d1PnjrrYsX22ixKVLm0E1Jlupqzx oCBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=WFw4V83F; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w1si12671422edt.288.2019.10.22.17.34.11; Tue, 22 Oct 2019 17:34:35 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=WFw4V83F; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732651AbfJWASi (ORCPT + 99 others); Tue, 22 Oct 2019 20:18:38 -0400 Received: from linux.microsoft.com ([13.77.154.182]:45298 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732315AbfJWAS0 (ORCPT ); Tue, 22 Oct 2019 20:18:26 -0400 Received: from nramas-ThinkStation-P520.corp.microsoft.com (unknown [131.107.174.108]) by linux.microsoft.com (Postfix) with ESMTPSA id 1B7132010AC8; Tue, 22 Oct 2019 17:18:25 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 1B7132010AC8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1571789905; bh=l3/xpxDJDNPHhTjWJ68OgeQThxUX96N97fTeydZwHaM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WFw4V83FIRb9/kKNS80AHaLOAxb18GAxUAoHQDsmgtjgeYqh4zjQTx/5eHQBz4A7W sg6wHJlSkrhtKDNqK5vSXxOCCWZiJYGcF3MRPLdr7YJmMvV9VOlZyVAtHySJPZsNT8 59WqKDVFBJd8zSoyI1OXfNViIfpKYIPGQcm2ymUY= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, dhowells@redhat.com, casey@schaufler-ca.com, sashal@kernel.org, jamorris@linux.microsoft.com, linux-security-module@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, keyrings@vger.kernel.org Cc: nramas@linux.microsoft.com Subject: [PATCH v1 6/6] KEYS: measure keys when they are created or updated Date: Tue, 22 Oct 2019 17:18:18 -0700 Message-Id: <20191023001818.3684-7-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191023001818.3684-1-nramas@linux.microsoft.com> References: <20191023001818.3684-1-nramas@linux.microsoft.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org A new LSM function namely, security_key_create_or_update, has been added. This function is called by key_create_or_update function when a new key is created or an existing key is updated. This call is made when the key has been instantiated and linked to the target keyring. security_key_create_or_update is passed the target keyring, key, key creation flags, and a boolean flag indicating whether the key was newly created or an existing key was updated. This function calls the ima function ima_post_key_create_or_update to measure the key. Signed-off-by: Lakshmi Ramasubramanian --- include/linux/ima.h | 15 +++++++- include/linux/security.h | 13 ++++++- security/keys/key.c | 78 +++++++++++++++++++++++++++++++++++----- security/security.c | 10 ++++++ 4 files changed, 105 insertions(+), 11 deletions(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index a20ad398d260..ce763901380d 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -24,7 +24,11 @@ extern int ima_post_read_file(struct file *file, void *buf, loff_t size, enum kernel_read_file_id id); extern void ima_post_path_mknod(struct dentry *dentry); extern void ima_kexec_cmdline(const void *buf, int size); - +extern int ima_post_key_create_or_update(struct key *keyring, + struct key *key, + const struct cred *cred, + unsigned long flags, + bool create); #ifdef CONFIG_IMA_KEXEC extern void ima_add_kexec_buffer(struct kimage *image); #endif @@ -91,6 +95,15 @@ static inline void ima_post_path_mknod(struct dentry *dentry) } static inline void ima_kexec_cmdline(const void *buf, int size) {} + +static inline int ima_post_key_create_or_update(struct key *keyring, + struct key *key, + const struct cred *cred, + unsigned long flags, + bool create) +{ + return 0; +} #endif /* CONFIG_IMA */ #ifndef CONFIG_IMA_KEXEC diff --git a/include/linux/security.h b/include/linux/security.h index 5f7441abbf42..c8348da3db2e 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1677,7 +1677,9 @@ void security_key_free(struct key *key); int security_key_permission(key_ref_t key_ref, const struct cred *cred, unsigned perm); int security_key_getsecurity(struct key *key, char **_buffer); - +int security_key_create_or_update(struct key *keyring, struct key *key, + const struct cred *cred, + unsigned long flags, bool create); #else static inline int security_key_alloc(struct key *key, @@ -1704,6 +1706,15 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) return 0; } +static inline int security_key_create_or_update(struct key *keyring, + struct key *key, + const struct cred *cred, + unsigned long flags, + bool create) +{ + return 0; +} + #endif #endif /* CONFIG_KEYS */ diff --git a/security/keys/key.c b/security/keys/key.c index 764f4c57913e..b913feaf196e 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -781,7 +781,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref, } /** - * key_create_or_update - Update or create and instantiate a key. + * __key_create_or_update - Update or create and instantiate a key. * @keyring_ref: A pointer to the destination keyring with possession flag. * @type: The type of key. * @description: The searchable description for the key. @@ -789,6 +789,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref, * @plen: The length of @payload. * @perm: The permissions mask for a new key. * @flags: The quota flags for a new key. + * @create: Set to true if the key was newly created. + * Set to false if the key was updated. * * Search the destination keyring for a key of the same description and if one * is found, update it, otherwise create and instantiate a new one and create a @@ -805,13 +807,14 @@ static inline key_ref_t __key_update(key_ref_t key_ref, * On success, the possession flag from the keyring ref will be tacked on to * the key ref before it is returned. */ -key_ref_t key_create_or_update(key_ref_t keyring_ref, - const char *type, - const char *description, - const void *payload, - size_t plen, - key_perm_t perm, - unsigned long flags) +static key_ref_t __key_create_or_update(key_ref_t keyring_ref, + const char *type, + const char *description, + const void *payload, + size_t plen, + key_perm_t perm, + unsigned long flags, + bool *create) { struct keyring_index_key index_key = { .description = description, @@ -936,6 +939,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, goto error_link_end; } + *create = true; key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); error_link_end: @@ -948,7 +952,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, error: return key_ref; - found_matching_key: +found_matching_key: /* we found a matching key, so we're going to try to update it * - we can drop the locks first as we have the key pinned */ @@ -964,9 +968,65 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, } } + *create = false; key_ref = __key_update(key_ref, &prep); goto error_free_prep; } + +/** + * key_create_or_update - Update or create and instantiate a key. + * @keyring_ref: A pointer to the destination keyring with possession flag. + * @type: The type of key. + * @description: The searchable description for the key. + * @payload: The data to use to instantiate or update the key. + * @plen: The length of @payload. + * @perm: The permissions mask for a new key. + * @flags: The quota flags for a new key. + * + * Calls the internal function __key_create_or_update. + * If successful calls the security LSM hook. + */ +key_ref_t key_create_or_update(key_ref_t keyring_ref, + const char *type, + const char *description, + const void *payload, + size_t plen, + key_perm_t perm, + unsigned long flags) +{ + key_ref_t key_ref; + struct key *keyring, *key = NULL; + int ret = 0; + bool create = false; + + key_ref = __key_create_or_update(keyring_ref, type, description, + payload, plen, perm, flags, + &create); + if (IS_ERR(key_ref)) + goto out; + + keyring = key_ref_to_ptr(keyring_ref); + key = key_ref_to_ptr(key_ref); + + /* let the security module know about + * the created or updated key. + */ + ret = security_key_create_or_update(keyring, key, + current_cred(), + flags, create); + if (ret < 0) + goto security_error; + else + goto out; + +security_error: + key_unlink(keyring, key); + key_put(key); + key_ref = ERR_PTR(ret); + +out: + return key_ref; +} EXPORT_SYMBOL(key_create_or_update); /** diff --git a/security/security.c b/security/security.c index 250ee2d76406..707a9e7fa94d 100644 --- a/security/security.c +++ b/security/security.c @@ -2303,6 +2303,16 @@ int security_key_getsecurity(struct key *key, char **_buffer) return call_int_hook(key_getsecurity, 0, key, _buffer); } +int security_key_create_or_update(struct key *keyring, + struct key *key, + const struct cred *cred, + unsigned long flags, + bool create) +{ + return ima_post_key_create_or_update(keyring, key, cred, + flags, create); +} + #endif /* CONFIG_KEYS */ #ifdef CONFIG_AUDIT -- 2.17.1