Changes since last update:

- fix shift-out-of-bounds of crafted blkszbits generated by syzkaller;
 
  - ensure initialized fields can only be observed after bit is set.
 -----BEGIN PGP SIGNATURE-----
 
 iIsEABYIADMWIQThPAmQN9sSA0DVxtI5NzHcH7XmBAUCYC5qFBUcaHNpYW5na2Fv
 QHJlZGhhdC5jb20ACgkQOTcx3B+15gT4PwD/W8BGqC3/uBC6qGJuNkRteFmaIDvB
 EplXizcZ+6ennkkBAIbbEsFx8K3TM/tg45YqV+ebjRbsH4NG1owVqb8ZAc0M
 =Ni8F
 -----END PGP SIGNATURE-----

Merge tag 'erofs-for-5.12-rc1' of git://git.kernel.org/pub/scm/linux/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
This commit is contained in:
Linus Torvalds 2021-02-21 10:19:34 -08:00
commit 681e2abe21
3 changed files with 20 additions and 4 deletions

View File

@ -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;
}

View File

@ -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;
@ -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:

View File

@ -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;
@ -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);