summaryrefslogtreecommitdiff
path: root/fs/crypto/policy.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2020-07-21 15:59:19 -0700
committerEric Biggers <ebiggers@google.com>2020-07-21 16:02:13 -0700
commitab673b987488c4fab7a0bc4824a48211f9d910e3 (patch)
tree16ec1d6324aa8c0fe60f3d5f45f35b65de43f2ae /fs/crypto/policy.c
parent777afe4e68d7ac37711d36098bea65650ec305a0 (diff)
fscrypt: use smp_load_acquire() for ->i_crypt_info
Normally smp_store_release() or cmpxchg_release() is paired with smp_load_acquire(). Sometimes smp_load_acquire() can be replaced with the more lightweight READ_ONCE(). However, for this to be safe, all the published memory must only be accessed in a way that involves the pointer itself. This may not be the case if allocating the object also involves initializing a static or global variable, for example. fscrypt_info includes various sub-objects which are internal to and are allocated by other kernel subsystems such as keyrings and crypto. So by using READ_ONCE() for ->i_crypt_info, we're relying on internal implementation details of these other kernel subsystems. Remove this fragile assumption by using smp_load_acquire() instead. (Note: I haven't seen any real-world problems here. This change is just fixing the code to be guaranteed correct and less fragile.) Fixes: e37a784d8b6a ("fscrypt: use READ_ONCE() to access ->i_crypt_info") Link: https://lore.kernel.org/r/20200721225920.114347-5-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@google.com>
Diffstat (limited to 'fs/crypto/policy.c')
-rw-r--r--fs/crypto/policy.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c
index 8e667aadf271..2d73fd39ad96 100644
--- a/fs/crypto/policy.c
+++ b/fs/crypto/policy.c
@@ -352,7 +352,7 @@ static int fscrypt_get_policy(struct inode *inode, union fscrypt_policy *policy)
union fscrypt_context ctx;
int ret;
- ci = READ_ONCE(inode->i_crypt_info);
+ ci = fscrypt_get_info(inode);
if (ci) {
/* key available, use the cached policy */
*policy = ci->ci_policy;
@@ -641,7 +641,7 @@ int fscrypt_inherit_context(struct inode *parent, struct inode *child,
if (res < 0)
return res;
- ci = READ_ONCE(parent->i_crypt_info);
+ ci = fscrypt_get_info(parent);
if (ci == NULL)
return -ENOKEY;