From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S970366AbdIZUOk (ORCPT ); Tue, 26 Sep 2017 16:14:40 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:37215 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S968670AbdIZUOa (ORCPT ); Tue, 26 Sep 2017 16:14:30 -0400 X-Google-Smtp-Source: AOwi7QDWL4kPtGvPdBJWKg8M2aPS6f7u1t8jRqi7gyqCbgPh1SdISIORXl5QX3ai0Ug+UDU0enWZXw== From: Eric Biggers To: keyrings@vger.kernel.org Cc: David Howells , Michael Halcrow , linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Biggers Subject: [PATCH v2 2/6] KEYS: load key flags atomically in key_is_instantiated() Date: Tue, 26 Sep 2017 13:11:01 -0700 Message-Id: <20170926201105.126166-3-ebiggers3@gmail.com> X-Mailer: git-send-email 2.14.1.992.g2c7b836f3a-goog In-Reply-To: <20170926201105.126166-1-ebiggers3@gmail.com> References: <20170926201105.126166-1-ebiggers3@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Biggers In key_is_instantiated(), we check for KEY_FLAG_INSTANTIATED set and KEY_FLAG_NEGATIVE unset. But this was done as two separate bit tests which were not atomic with respect to each other, and had no memory barrier providing ordering. Therefore, it was theoretically possible for the function to incorrectly return true if called while the key was being negatively instantiated. There also needs to be a memory barrier before anything which is only meaningful for positively instantiated keys, e.g. ->payload and ->datalen, can be read --- which some of the ->describe() methods do. Fix both these problems by loading the flags using smp_load_acquire(). Signed-off-by: Eric Biggers --- include/linux/key.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/linux/key.h b/include/linux/key.h index b7b590d7c480..fcb79eedbdb5 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -372,8 +372,11 @@ extern void key_set_timeout(struct key *, unsigned); */ static inline bool key_is_instantiated(const struct key *key) { - return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && - !test_bit(KEY_FLAG_NEGATIVE, &key->flags); + /* Pairs with RELEASE in mark_key_instantiated() */ + unsigned long flags = smp_load_acquire(&key->flags); + + return (flags & KEY_FLAG_INSTANTIATED) && + !(flags & KEY_FLAG_NEGATIVE); } #define dereference_key_rcu(KEY) \ -- 2.14.1.992.g2c7b836f3a-goog