Skip to content

Commit

Permalink
Merge tag 'erofs-for-5.12-rc1' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/xiang/erofs

Pull erofs updates from Gao Xiang:
 "This contains a somewhat important but rarely reproduced fix reported
  month ago for platforms which have weak memory model (e.g. arm64).

  The root cause is that test_bit/set_bit atomic operations are actually
  implemented in relaxed forms, and uninitialized fields governed by an
  atomic bit could be observed in advance due to memory reordering thus
  memory barrier pairs should be used.

  There is also a trivial fix of crafted blkszbits generated by
  syzkaller.

  Summary:

   - fix shift-out-of-bounds of crafted blkszbits generated by syzkaller

   - ensure initialized fields can only be observed after bit is set"

* tag 'erofs-for-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
  erofs: initialized fields can only be observed after bit is set
  erofs: fix shift-out-of-bounds of blkszbits
  • Loading branch information
torvalds committed Feb 21, 2021
2 parents 8b42fe1 + ce06312 commit 681e2ab
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 4 deletions.
4 changes: 2 additions & 2 deletions fs/erofs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ static int erofs_read_superblock(struct super_block *sb)
blkszbits = dsb->blkszbits;
/* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */
if (blkszbits != LOG_BLOCK_SIZE) {
erofs_err(sb, "blksize %u isn't supported on this platform",
1 << blkszbits);
erofs_err(sb, "blkszbits %u isn't supported on this platform",
blkszbits);
goto out;
}

Expand Down
10 changes: 9 additions & 1 deletion fs/erofs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@ static int init_inode_xattrs(struct inode *inode)
int ret = 0;

/* the most case is that xattrs of this inode are initialized. */
if (test_bit(EROFS_I_EA_INITED_BIT, &vi->flags))
if (test_bit(EROFS_I_EA_INITED_BIT, &vi->flags)) {
/*
* paired with smp_mb() at the end of the function to ensure
* fields will only be observed after the bit is set.
*/
smp_mb();
return 0;
}

if (wait_on_bit_lock(&vi->flags, EROFS_I_BL_XATTR_BIT, TASK_KILLABLE))
return -ERESTARTSYS;
Expand Down Expand Up @@ -137,6 +143,8 @@ static int init_inode_xattrs(struct inode *inode)
}
xattr_iter_end(&it, atomic_map);

/* paired with smp_mb() at the beginning of the function. */
smp_mb();
set_bit(EROFS_I_EA_INITED_BIT, &vi->flags);

out_unlock:
Expand Down
10 changes: 9 additions & 1 deletion fs/erofs/zmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,14 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
void *kaddr;
struct z_erofs_map_header *h;

if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags))
if (test_bit(EROFS_I_Z_INITED_BIT, &vi->flags)) {
/*
* paired with smp_mb() at the end of the function to ensure
* fields will only be observed after the bit is set.
*/
smp_mb();
return 0;
}

if (wait_on_bit_lock(&vi->flags, EROFS_I_BL_Z_BIT, TASK_KILLABLE))
return -ERESTARTSYS;
Expand Down Expand Up @@ -83,6 +89,8 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)

vi->z_physical_clusterbits[1] = vi->z_logical_clusterbits +
((h->h_clusterbits >> 5) & 7);
/* paired with smp_mb() at the beginning of the function */
smp_mb();
set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
unmap_done:
kunmap_atomic(kaddr);
Expand Down

0 comments on commit 681e2ab

Please sign in to comment.