Commit 5577416c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fsverity-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt

Pull fsverity update from Eric Biggers:
 "One fix for fs/verity/ to strengthen a memory barrier which might be
  too weak. This mirrors a similar fix in fs/crypto/"

* tag 'fsverity-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt:
  fs-verity: use smp_load_acquire() for ->i_verity_info
parents 690b2567 f3db0bed
...@@ -221,11 +221,20 @@ struct fsverity_info *fsverity_create_info(const struct inode *inode, ...@@ -221,11 +221,20 @@ struct fsverity_info *fsverity_create_info(const struct inode *inode,
void fsverity_set_info(struct inode *inode, struct fsverity_info *vi) void fsverity_set_info(struct inode *inode, struct fsverity_info *vi)
{ {
/* /*
* Multiple processes may race to set ->i_verity_info, so use cmpxchg. * Multiple tasks may race to set ->i_verity_info, so use
* This pairs with the READ_ONCE() in fsverity_get_info(). * cmpxchg_release(). This pairs with the smp_load_acquire() in
* fsverity_get_info(). I.e., here we publish ->i_verity_info with a
* RELEASE barrier so that other tasks can ACQUIRE it.
*/ */
if (cmpxchg(&inode->i_verity_info, NULL, vi) != NULL) if (cmpxchg_release(&inode->i_verity_info, NULL, vi) != NULL) {
/* Lost the race, so free the fsverity_info we allocated. */
fsverity_free_info(vi); fsverity_free_info(vi);
/*
* Afterwards, the caller may access ->i_verity_info directly,
* so make sure to ACQUIRE the winning fsverity_info.
*/
(void)fsverity_get_info(inode);
}
} }
void fsverity_free_info(struct fsverity_info *vi) void fsverity_free_info(struct fsverity_info *vi)
......
...@@ -115,8 +115,13 @@ struct fsverity_operations { ...@@ -115,8 +115,13 @@ struct fsverity_operations {
static inline struct fsverity_info *fsverity_get_info(const struct inode *inode) static inline struct fsverity_info *fsverity_get_info(const struct inode *inode)
{ {
/* pairs with the cmpxchg() in fsverity_set_info() */ /*
return READ_ONCE(inode->i_verity_info); * Pairs with the cmpxchg_release() in fsverity_set_info().
* I.e., another task may publish ->i_verity_info concurrently,
* executing a RELEASE barrier. We need to use smp_load_acquire() here
* to safely ACQUIRE the memory the other task published.
*/
return smp_load_acquire(&inode->i_verity_info);
} }
/* enable.c */ /* enable.c */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment