From patchwork Thu Sep 28 21:26:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 9976755 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0B50C60375 for ; Thu, 28 Sep 2017 21:30:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F110B29758 for ; Thu, 28 Sep 2017 21:29:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E5DF62975A; Thu, 28 Sep 2017 21:29:59 +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=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 88F7F29758 for ; Thu, 28 Sep 2017 21:29:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751905AbdI1V35 (ORCPT ); Thu, 28 Sep 2017 17:29:57 -0400 Received: from mail-pg0-f68.google.com ([74.125.83.68]:38077 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751702AbdI1V3v (ORCPT ); Thu, 28 Sep 2017 17:29:51 -0400 Received: by mail-pg0-f68.google.com with SMTP id y192so1983096pgd.5; Thu, 28 Sep 2017 14:29:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QIf5TvSwlxXBfAbufIBbGGWdIVybkIeIgF5Og7An4AA=; b=osYSvKTuetUwE53di/XjOHEX5Rm3jcvYedz3/SSE9N9wZf4TJ5NvH3OKgmeEiDk6rW 56T18rD3hF4FYWCGby+/nwF83zvwptjb/fG4Ev1ibOT7ZorFS3d4vNE0juVNRS80hr1x ZbVsOIsoTp375gcxcAdP6Qdi/vB3VKyFGiopnSpRrJ0HPcrJHMmjNRJR3dqJuUkxSNN/ AfAngz1H97fFHmwmU7bIWa3HqAWFSp3fjGPDjYfIxG68IlP4s8vuHdEiNxIESmPBLI2j xE5nUj4CgJHpiZkeQ1FffjkPo7fv844e+dZ9H51QXZr/PKKAt82Bhb0VUrH0ChGkI8lf DurQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QIf5TvSwlxXBfAbufIBbGGWdIVybkIeIgF5Og7An4AA=; b=g8eHJWk9BbIxywb8KJFscSZ+goBBzcDYXoyeRuzh3b0CR9CYfWkjzTMZtOevz+da+S 3VOgS0Wlg4LlDs29LKGRHniX1+v7+hNykm2FAIwY+RKAk/DVxNBNQjkmXrra4mRlH7Ys IDJ84sfVAvrZ76lQhAukj3wuQXvn2tTzWvDiMnWhM4IRBFNIYHmKG0DYMi1Ht/G5RY4s ZY65fUGD/ig5qQSMyFrAFo9OUN2RTLxxLOq2I8NcibwJxbnUFJVJ7M2BlrwlMzBlTAMH j0ZlA1Rt09zOq7mdU1hhYnw9mc+/J/HMcmUOnY4qWjq4Kl2B+QJtkvQJ2AeM3wIYLla5 GmmQ== X-Gm-Message-State: AHPjjUjafaKLfQoLKJzZnY/5WuEtB7FhUXCDmWamsdDaq5XY8m2R/dil AFl8ToPKojVLloGQPyCturWk6Qqq X-Google-Smtp-Source: AOwi7QDMlwLo+X9MVG57p9CLesnQltvq46KxaTNRRKp1vhF/83uU78R3JdXu4utHAYGqaNqwnTOEbw== X-Received: by 10.98.72.83 with SMTP id v80mr5590962pfa.54.1506634190304; Thu, 28 Sep 2017 14:29:50 -0700 (PDT) Received: from ebiggers-linuxstation.kir.corp.google.com ([100.66.174.81]) by smtp.gmail.com with ESMTPSA id o128sm3810672pga.5.2017.09.28.14.29.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 28 Sep 2017 14:29:49 -0700 (PDT) From: Eric Biggers To: keyrings@vger.kernel.org Cc: David Howells , Michael Halcrow , linux-cachefs@redhat.com, ecryptfs@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-security-module@vger.kernel.org, Eric Biggers , stable@vger.kernel.org Subject: [PATCH 5/7] ecryptfs: fix dereference of NULL user_key_payload Date: Thu, 28 Sep 2017 14:26:00 -0700 Message-Id: <20170928212602.41744-6-ebiggers3@gmail.com> X-Mailer: git-send-email 2.14.2.822.g60be5d43e6-goog In-Reply-To: <20170928212602.41744-1-ebiggers3@gmail.com> References: <20170928212602.41744-1-ebiggers3@gmail.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers In eCryptfs, we failed to verify that the authentication token keys are not revoked before dereferencing their payloads, which is problematic because the payload of a revoked key is NULL. request_key() *does* skip revoked keys, but there is still a window where the key can be revoked before we acquire the key semaphore. Fix it by updating ecryptfs_get_key_payload_data() to return -EKEYREVOKED if the key payload is NULL. For completeness we check this for "encrypted" keys as well as "user" keys, although encrypted keys cannot be revoked currently. Alternatively we could use key_validate(), but since we'll also need to fix ecryptfs_get_key_payload_data() to validate the payload length, it seems appropriate to just check the payload pointer. Fixes: 237fead61998 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig") Cc: [v2.6.19+] Signed-off-by: Eric Biggers Reviewed-by: James Morris --- fs/ecryptfs/ecryptfs_kernel.h | 24 +++++++++++++++++------- fs/ecryptfs/keystore.c | 9 ++++++++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 9c351bf757b2..3fbc0ff79699 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context { static inline struct ecryptfs_auth_tok * ecryptfs_get_encrypted_key_payload_data(struct key *key) { - if (key->type == &key_type_encrypted) - return (struct ecryptfs_auth_tok *) - (&((struct encrypted_key_payload *)key->payload.data[0])->payload_data); - else + struct encrypted_key_payload *payload; + + if (key->type != &key_type_encrypted) return NULL; + + payload = key->payload.data[0]; + if (!payload) + return ERR_PTR(-EKEYREVOKED); + + return (struct ecryptfs_auth_tok *)payload->payload_data; } static inline struct key *ecryptfs_get_encrypted_key(char *sig) @@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok * ecryptfs_get_key_payload_data(struct key *key) { struct ecryptfs_auth_tok *auth_tok; + struct user_key_payload *ukp; auth_tok = ecryptfs_get_encrypted_key_payload_data(key); - if (!auth_tok) - return (struct ecryptfs_auth_tok *)user_key_payload_locked(key)->data; - else + if (auth_tok) return auth_tok; + + ukp = user_key_payload_locked(key); + if (!ukp) + return ERR_PTR(-EKEYREVOKED); + + return (struct ecryptfs_auth_tok *)ukp->data; } #define ECRYPTFS_MAX_KEYSET_SIZE 1024 diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 3cf1546dca82..fa218cd64f74 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -459,7 +459,8 @@ static int ecryptfs_verify_version(u16 version) * @auth_tok_key: key containing the authentication token * @auth_tok: authentication token * - * Returns zero on valid auth tok; -EINVAL otherwise + * Returns zero on valid auth tok; -EINVAL if the payload is invalid; or + * -EKEYREVOKED if the key was revoked before we acquired its semaphore. */ static int ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, @@ -468,6 +469,12 @@ ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, int rc = 0; (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key); + if (IS_ERR(*auth_tok)) { + rc = PTR_ERR(*auth_tok); + *auth_tok = NULL; + goto out; + } + if (ecryptfs_verify_version((*auth_tok)->version)) { printk(KERN_ERR "Data structure version mismatch. Userspace " "tools must match eCryptfs kernel module with major "