History

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

Linus Torvalds committed 6 years ago

Commit 55774162 parents 690b256 f3db0be2 files · +19 −5Browse files

Unified · Split

2 files
  1. fs/verity/open.c +12 −3
  2. include/linux/fsverity.h +7 −2
fs/verity/open.c+12−3
@@ -221,11 +221,20 @@ out: · 220 unmodified lines
221void fsverity_set_info(struct inode *inode, struct fsverity_info *vi)221void fsverity_set_info(struct inode *inode, struct fsverity_info *vi)
222{222{
223 /*223 /*
224 * Multiple processes may race to set ->i_verity_info, so use cmpxchg.224 * Multiple tasks may race to set ->i_verity_info, so use
225 * This pairs with the READ_ONCE() in fsverity_get_info().225 * cmpxchg_release(). This pairs with the smp_load_acquire() in
226 * fsverity_get_info(). I.e., here we publish ->i_verity_info with a
227 * RELEASE barrier so that other tasks can ACQUIRE it.
226 */228 */
227 if (cmpxchg(&inode->i_verity_info, NULL, vi) != NULL)229 if (cmpxchg_release(&inode->i_verity_info, NULL, vi) != NULL) {
230 /* Lost the race, so free the fsverity_info we allocated. */
228 fsverity_free_info(vi);231 fsverity_free_info(vi);
232 /*
233 * Afterwards, the caller may access ->i_verity_info directly,
234 * so make sure to ACQUIRE the winning fsverity_info.
235 */
236 (void)fsverity_get_info(inode);
237 }
229}238}
230 239
231void fsverity_free_info(struct fsverity_info *vi)240void fsverity_free_info(struct fsverity_info *vi)
include/linux/fsverity.h+7−2
@@ -115,8 +115,13 @@ struct fsverity_operations { · 114 unmodified lines
115 115
116static inline struct fsverity_info *fsverity_get_info(const struct inode *inode)116static inline struct fsverity_info *fsverity_get_info(const struct inode *inode)
117{117{
118 /* pairs with the cmpxchg() in fsverity_set_info() */118 /*
119 return READ_ONCE(inode->i_verity_info);119 * Pairs with the cmpxchg_release() in fsverity_set_info().
120 * I.e., another task may publish ->i_verity_info concurrently,
121 * executing a RELEASE barrier. We need to use smp_load_acquire() here
122 * to safely ACQUIRE the memory the other task published.
123 */
124 return smp_load_acquire(&inode->i_verity_info);
120}125}
121 126
122/* enable.c */127/* enable.c */