From patchwork Fri Sep 7 22:39:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 10592685 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B2A8714E2 for ; Fri, 7 Sep 2018 22:38:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A1F032B627 for ; Fri, 7 Sep 2018 22:38:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9497C2B630; Fri, 7 Sep 2018 22:38:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 24FD82B627 for ; Fri, 7 Sep 2018 22:38:31 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 248C78E000E; Fri, 7 Sep 2018 18:38:25 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 1FA368E0001; Fri, 7 Sep 2018 18:38:25 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0E8E28E000E; Fri, 7 Sep 2018 18:38:25 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.198]) by kanga.kvack.org (Postfix) with ESMTP id C39168E0001 for ; Fri, 7 Sep 2018 18:38:24 -0400 (EDT) Received: by mail-pg1-f198.google.com with SMTP id l125-v6so7821294pga.1 for ; Fri, 07 Sep 2018 15:38:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:date:from:to :cc:subject:message-id:references:mime-version:content-disposition :in-reply-to:user-agent; bh=+D5QaT8Xq9yQk4z5mqRblcRqBWqth6l2feIxickBdQY=; b=S4q4D+RZC8s+qA6bg1Tyu2WOFaVkxjueWXb10s35XW7KUkQtOKDVxaBsJYt4XfpeR3 zxhMi6WMtNWyYy+VK+ndAUWX/DmhRpOh2gF7i8JKdeorjjCTj0xGwqWBaEpTUQHkYU6l sJEPa6vHooOjUr1K8Gi7g3gjpmCnRzQGagjABX0i1JcKnVIq00JLtDk3o1Hf7NPyMzYo elbr4nQs0TbRfEmlau9gaQYfcrPHvOex2NIRfk1NtR0s3udgzHXezl1IWNiEXMumIt8e KQzaeFVpUnbkToT86FYeIsPSGBHX7C5YW7wyd786Kqzi1ok8WeBxVpYAtGPP2ClUZwna I9VQ== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of alison.schofield@intel.com designates 134.134.136.24 as permitted sender) smtp.mailfrom=alison.schofield@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: APzg51BCe5oOLd2hPYL8dlw4NiTqHGWrfeFMk5C6+rUGgwOtw4/LOqcg eoCft+t0e6F6sPsP3J3nyotckOJjSnwqoYk/ihPhUk7k8rkkjvCon6caPaZ9GDPyXN42nZJ9Bnp GMp6LCr2l4xUonnFHCrm7R4A8iDkTpfI+c6MgnUBxi5fVmDX4Gi/jEENB+qla+SF2SQ== X-Received: by 2002:a63:6283:: with SMTP id w125-v6mr10179797pgb.83.1536359904464; Fri, 07 Sep 2018 15:38:24 -0700 (PDT) X-Google-Smtp-Source: ANB0VdZO45mBNdNHHBm+qPnZ+ADL2Quzarx8NnZjpQBtIuC7iZq28nNd7Xo8D6MPpH6JB8WziVz5 X-Received: by 2002:a63:6283:: with SMTP id w125-v6mr10179727pgb.83.1536359903422; Fri, 07 Sep 2018 15:38:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536359903; cv=none; d=google.com; s=arc-20160816; b=aJN4foph/H64iKSVEZAPyONQ/4tH3bDPIa7rE8CwptMBSVCuvQkKRobnPKHENQeD05 pTJcrB/iL3nVH5jqsxnf2lzgdS6t/fnHDRdzTAeYJmTnhDJUhuKYT4lnoRgPUghvnYmn aD12IYFtvi3Kf0J16erqbdygmQirLv5+5GA7XKuQutTw/U0SD/SUkjctr7bD+E33VIRH vCDiZZLEg/ON9U4tFmJd10IrXkqfBHqKOx9XzCZEEFHaqkStqOGdt7t9E61i8LBXhiHS Rz6SDe4+iY9YOC4c1S/0ZEjHg+5alToAkmGnGmGiiVLbBs/MpZ4Lx+gqBzTa9xvG+Z8q 87Ww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=user-agent:in-reply-to:content-disposition:mime-version:references :message-id:subject:cc:to:from:date; bh=+D5QaT8Xq9yQk4z5mqRblcRqBWqth6l2feIxickBdQY=; b=a2XIry9kllCCL95MOa3s/q9tJ6zueJYCmqLLSh4NqyukYYV5gFW54tzckEqSoLk4xO b6FQMC+5rMMm0uXDobQXFvi3v1p2VTDuvlKSnLWsouMpeToJjkvi4AFTvLOdVG3lCxdD TEKgkRxJugpNX2awg5T/KO/tdDMejOUuNgSCOtZa29ov+dWJf9fGBQXToXmx956kncCT tPWlNwPxusBlnsQyzHBGupDR+p+BmCB3EBjebzUgwOUVzFT8C6A2AcXSGdayGnB8BgG7 /RsMoPtxN+bHmmFiq7XivjkzTs36/bwGhP3/4iAkNqUbIOD9afrOu4KY55nPXT+mXsJ+ 7kDA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of alison.schofield@intel.com designates 134.134.136.24 as permitted sender) smtp.mailfrom=alison.schofield@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga09.intel.com (mga09.intel.com. [134.134.136.24]) by mx.google.com with ESMTPS id g16-v6si9200184pgi.373.2018.09.07.15.38.23 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 07 Sep 2018 15:38:23 -0700 (PDT) Received-SPF: pass (google.com: domain of alison.schofield@intel.com designates 134.134.136.24 as permitted sender) client-ip=134.134.136.24; Authentication-Results: mx.google.com; spf=pass (google.com: domain of alison.schofield@intel.com designates 134.134.136.24 as permitted sender) smtp.mailfrom=alison.schofield@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: UNSCANNABLE X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Sep 2018 15:38:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,344,1531810800"; d="scan'208";a="261684753" Received: from alison-desk.jf.intel.com ([10.54.74.53]) by fmsmga006.fm.intel.com with ESMTP; 07 Sep 2018 15:38:22 -0700 Date: Fri, 7 Sep 2018 15:39:04 -0700 From: Alison Schofield To: dhowells@redhat.com, tglx@linutronix.de Cc: Kai Huang , Jun Nakajima , Kirill Shutemov , Dave Hansen , Jarkko Sakkinen , jmorris@namei.org, keyrings@vger.kernel.org, linux-security-module@vger.kernel.org, mingo@redhat.com, hpa@zytor.com, x86@kernel.org, linux-mm@kvack.org Subject: [RFC 12/12] keys/mktme: Do not revoke in use memory encryption keys Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP The MKTME key service maps userspace keys to hardware keyids. Those keys are used in a new system call that encrypts memory. The keys need to be tightly controlled. One example is that userspace keys should not be revoked while the hardware keyid slot is still in use. The KEY_FLAG_KEEP bit offers good control. The mktme service uses that flag to prevent userspace keys from going away without proper synchronization with the mktme service type. The problem is that we need a safe and synchronous way to revoke keys. The way .revoke methods function now, the key service type is called late in the revoke process for cleanup after the fact. The mktme key service has no means to consider and perhaps reject the revoke request. This proposal inserts the MKTME revoke call earlier into the existing keyctl path. If it is safe to revoke the key, MKTME key service will turn off KEY_FLAG_KEEP and let the revoke continue and succeed. Otherwise, not safe, KEY_FLAG_KEEP stays on, which causes the normal path of revoke to fail. For the MKTME Key Service, a revoke may be done safely when there are no outstanding memory mappings encrypted with the key being revoked. Signed-off-by: Alison Schofield --- security/keys/internal.h | 6 ++++++ security/keys/keyctl.c | 7 +++++++ security/keys/mktme_keys.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/security/keys/internal.h b/security/keys/internal.h index 9f8208dc0e55..9fb871522efe 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -316,4 +316,10 @@ static inline void key_check(const struct key *key) #endif +#ifdef CONFIG_MKTME_KEYS +extern void mktme_revoke_key(struct key *key); +#else +static inline void mktme_revoke_key(struct key *key) {} +#endif /* CONFIG_MKTME_KEYS */ + #endif /* _INTERNAL_H */ diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 1ffe60bb2845..86d2596ff275 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -363,6 +363,9 @@ long keyctl_update_key(key_serial_t id, * and any links to the key will be automatically garbage collected after a * certain amount of time (/proc/sys/kernel/keys/gc_delay). * + * The MKTME key service type checks if a memory encryption key is in use + * before allowing a revoke to proceed. + * * Keys with KEY_FLAG_KEEP set should not be revoked. * * If successful, 0 is returned. @@ -387,6 +390,10 @@ long keyctl_revoke_key(key_serial_t id) key = key_ref_to_ptr(key_ref); ret = 0; + + if (strcmp(key->type->name, "mktme") == 0) + mktme_revoke_key(key); + if (test_bit(KEY_FLAG_KEEP, &key->flags)) ret = -EPERM; else diff --git a/security/keys/mktme_keys.c b/security/keys/mktme_keys.c index dcbce7194647..c665be860538 100644 --- a/security/keys/mktme_keys.c +++ b/security/keys/mktme_keys.c @@ -31,6 +31,52 @@ static const char * const mktme_program_err[] = { "Failure to access key table", /* 5 */ }; +static int mktme_clear_programmed_key(int keyid) +{ + struct mktme_key_program *kprog = NULL; + int ret; + + kprog = kmem_cache_zalloc(mktme_prog_cache, GFP_KERNEL); + if (!kprog) + return -ENOMEM; + + kprog->keyid = keyid; + kprog->keyid_ctrl = MKTME_KEYID_CLEAR_KEY; + ret = mktme_key_program(kprog, mktme_cpumask); + if (ret == MKTME_PROG_SUCCESS) + mktme_map_clear_keyid(keyid); + else + pr_debug("mktme: %s [%d]\n", mktme_program_err[ret], ret); + + kmem_cache_free(mktme_prog_cache, kprog); + return ret; +} + +/* + * If the key is not in use, clear the hardware programming and + * allow the revoke to continue by clearing KEY_FLAG_KEEP. + */ +void mktme_revoke_key(struct key *key) +{ + int keyid, vma_count; + + mktme_map_lock(); + keyid = mktme_map_keyid_from_serial(key->serial); + if (keyid <= 0) + goto out; + + vma_count = vma_read_encrypt_ref(keyid); + if (vma_count > 0) { + pr_debug("mktme not freeing keyid[%d] encrypt_count[%d]\n", + keyid, vma_count); + goto out; + } + if (!mktme_clear_programmed_key(keyid)) + clear_bit(KEY_FLAG_KEEP, &key->flags); +out: + mktme_map_unlock(); +} + /* If a key is available, program and add the key to the software map. */ static int mktme_program_key(key_serial_t serial, struct mktme_key_program *kprog) @@ -193,6 +239,7 @@ int mktme_instantiate(struct key *key, struct key_preparsed_payload *prep) mktme_map_lock(); ret = mktme_program_key(key->serial, kprog); + set_bit(KEY_FLAG_KEEP, &key->flags); mktme_map_unlock(); out: kzfree(options);