Merge tag 'fuse-fixes-5.15-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

Pull fuse fixes from Miklos Szeredi:
"Syzbot discovered a race in case of reusing the fuse sb (introduced in
this cycle).

Fix it by doing the s_fs_info initialization at the proper place"

* tag 'fuse-fixes-5.15-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
fuse: clean up error exits in fuse_fill_super()
fuse: always initialize sb->s_fs_info
fuse: clean up fuse_mount destruction
fuse: get rid of fuse_put_super()
fuse: check s_root when destroying sb

+46 -56
+3
fs/fuse/fuse_i.h
··· 1121 */ 1122 void fuse_conn_destroy(struct fuse_mount *fm); 1123 1124 /** 1125 * Add connection to control filesystem 1126 */
··· 1121 */ 1122 void fuse_conn_destroy(struct fuse_mount *fm); 1123 1124 + /* Drop the connection and free the fuse mount */ 1125 + void fuse_mount_destroy(struct fuse_mount *fm); 1126 + 1127 /** 1128 * Add connection to control filesystem 1129 */
+39 -48
fs/fuse/inode.c
··· 457 } 458 } 459 460 - static void fuse_put_super(struct super_block *sb) 461 - { 462 - struct fuse_mount *fm = get_fuse_mount_super(sb); 463 - 464 - fuse_conn_put(fm->fc); 465 - kfree(fm); 466 - } 467 - 468 static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr) 469 { 470 stbuf->f_type = FUSE_SUPER_MAGIC; ··· 995 .evict_inode = fuse_evict_inode, 996 .write_inode = fuse_write_inode, 997 .drop_inode = generic_delete_inode, 998 - .put_super = fuse_put_super, 999 .umount_begin = fuse_umount_begin, 1000 .statfs = fuse_statfs, 1001 .sync_fs = fuse_sync_fs, ··· 1415 if (!fm) 1416 return -ENOMEM; 1417 1418 fsc->s_fs_info = fm; 1419 sb = sget_fc(fsc, NULL, set_anon_super_fc); 1420 - if (IS_ERR(sb)) { 1421 - kfree(fm); 1422 return PTR_ERR(sb); 1423 - } 1424 - fm->fc = fuse_conn_get(fc); 1425 1426 /* Initialize superblock, making @mp_fi its root */ 1427 err = fuse_fill_super_submount(sb, mp_fi); 1428 if (err) { 1429 - fuse_conn_put(fc); 1430 - kfree(fm); 1431 - sb->s_fs_info = NULL; 1432 deactivate_locked_super(sb); 1433 return err; 1434 } ··· 1557 { 1558 struct fuse_fs_context *ctx = fsc->fs_private; 1559 int err; 1560 - struct fuse_conn *fc; 1561 - struct fuse_mount *fm; 1562 1563 if (!ctx->file || !ctx->rootmode_present || 1564 !ctx->user_id_present || !ctx->group_id_present) ··· 1566 * Require mount to happen from the same user namespace which 1567 * opened /dev/fuse to prevent potential attacks. 1568 */ 1569 - err = -EINVAL; 1570 if ((ctx->file->f_op != &fuse_dev_operations) || 1571 (ctx->file->f_cred->user_ns != sb->s_user_ns)) 1572 - goto err; 1573 ctx->fudptr = &ctx->file->private_data; 1574 - 1575 - fc = kmalloc(sizeof(*fc), GFP_KERNEL); 1576 - err = -ENOMEM; 1577 - if (!fc) 1578 - goto err; 1579 - 1580 - fm = kzalloc(sizeof(*fm), GFP_KERNEL); 1581 - if (!fm) { 1582 - kfree(fc); 1583 - goto err; 1584 - } 1585 - 1586 - fuse_conn_init(fc, fm, sb->s_user_ns, &fuse_dev_fiq_ops, NULL); 1587 - fc->release = fuse_free_conn; 1588 - 1589 - sb->s_fs_info = fm; 1590 1591 err = fuse_fill_super_common(sb, ctx); 1592 if (err) 1593 - goto err_put_conn; 1594 /* file->private_data shall be visible on all CPUs after this */ 1595 smp_mb(); 1596 fuse_send_init(get_fuse_mount_super(sb)); 1597 return 0; 1598 - 1599 - err_put_conn: 1600 - fuse_conn_put(fc); 1601 - kfree(fm); 1602 - sb->s_fs_info = NULL; 1603 - err: 1604 - return err; 1605 } 1606 1607 /* ··· 1599 { 1600 struct fuse_fs_context *ctx = fsc->fs_private; 1601 struct fuse_dev *fud; 1602 struct super_block *sb; 1603 int err; 1604 1605 if (ctx->fd_present) 1606 ctx->file = fget(ctx->fd); 1607 1608 if (IS_ENABLED(CONFIG_BLOCK) && ctx->is_bdev) { 1609 err = get_tree_bdev(fsc, fuse_fill_super); 1610 - goto out_fput; 1611 } 1612 /* 1613 * While block dev mount can be initialized with a dummy device fd 1614 * (found by device name), normal fuse mounts can't 1615 */ 1616 if (!ctx->file) 1617 - return -EINVAL; 1618 1619 /* 1620 * Allow creating a fuse mount with an already initialized fuse ··· 1648 } else { 1649 err = get_tree_nodev(fsc, fuse_fill_super); 1650 } 1651 - out_fput: 1652 if (ctx->file) 1653 fput(ctx->file); 1654 return err; ··· 1729 struct fuse_mount *fm = get_fuse_mount_super(sb); 1730 bool last; 1731 1732 - if (fm) { 1733 last = fuse_mount_remove(fm); 1734 if (last) 1735 fuse_conn_destroy(fm); 1736 } 1737 } 1738 1739 static void fuse_kill_sb_anon(struct super_block *sb) 1740 { 1741 fuse_sb_destroy(sb); 1742 kill_anon_super(sb); 1743 } 1744 1745 static struct file_system_type fuse_fs_type = { ··· 1765 { 1766 fuse_sb_destroy(sb); 1767 kill_block_super(sb); 1768 } 1769 1770 static struct file_system_type fuseblk_fs_type = {
··· 457 } 458 } 459 460 static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr) 461 { 462 stbuf->f_type = FUSE_SUPER_MAGIC; ··· 1003 .evict_inode = fuse_evict_inode, 1004 .write_inode = fuse_write_inode, 1005 .drop_inode = generic_delete_inode, 1006 .umount_begin = fuse_umount_begin, 1007 .statfs = fuse_statfs, 1008 .sync_fs = fuse_sync_fs, ··· 1424 if (!fm) 1425 return -ENOMEM; 1426 1427 + fm->fc = fuse_conn_get(fc); 1428 fsc->s_fs_info = fm; 1429 sb = sget_fc(fsc, NULL, set_anon_super_fc); 1430 + if (fsc->s_fs_info) 1431 + fuse_mount_destroy(fm); 1432 + if (IS_ERR(sb)) 1433 return PTR_ERR(sb); 1434 1435 /* Initialize superblock, making @mp_fi its root */ 1436 err = fuse_fill_super_submount(sb, mp_fi); 1437 if (err) { 1438 deactivate_locked_super(sb); 1439 return err; 1440 } ··· 1569 { 1570 struct fuse_fs_context *ctx = fsc->fs_private; 1571 int err; 1572 1573 if (!ctx->file || !ctx->rootmode_present || 1574 !ctx->user_id_present || !ctx->group_id_present) ··· 1580 * Require mount to happen from the same user namespace which 1581 * opened /dev/fuse to prevent potential attacks. 1582 */ 1583 if ((ctx->file->f_op != &fuse_dev_operations) || 1584 (ctx->file->f_cred->user_ns != sb->s_user_ns)) 1585 + return -EINVAL; 1586 ctx->fudptr = &ctx->file->private_data; 1587 1588 err = fuse_fill_super_common(sb, ctx); 1589 if (err) 1590 + return err; 1591 /* file->private_data shall be visible on all CPUs after this */ 1592 smp_mb(); 1593 fuse_send_init(get_fuse_mount_super(sb)); 1594 return 0; 1595 } 1596 1597 /* ··· 1637 { 1638 struct fuse_fs_context *ctx = fsc->fs_private; 1639 struct fuse_dev *fud; 1640 + struct fuse_conn *fc; 1641 + struct fuse_mount *fm; 1642 struct super_block *sb; 1643 int err; 1644 + 1645 + fc = kmalloc(sizeof(*fc), GFP_KERNEL); 1646 + if (!fc) 1647 + return -ENOMEM; 1648 + 1649 + fm = kzalloc(sizeof(*fm), GFP_KERNEL); 1650 + if (!fm) { 1651 + kfree(fc); 1652 + return -ENOMEM; 1653 + } 1654 + 1655 + fuse_conn_init(fc, fm, fsc->user_ns, &fuse_dev_fiq_ops, NULL); 1656 + fc->release = fuse_free_conn; 1657 + 1658 + fsc->s_fs_info = fm; 1659 1660 if (ctx->fd_present) 1661 ctx->file = fget(ctx->fd); 1662 1663 if (IS_ENABLED(CONFIG_BLOCK) && ctx->is_bdev) { 1664 err = get_tree_bdev(fsc, fuse_fill_super); 1665 + goto out; 1666 } 1667 /* 1668 * While block dev mount can be initialized with a dummy device fd 1669 * (found by device name), normal fuse mounts can't 1670 */ 1671 + err = -EINVAL; 1672 if (!ctx->file) 1673 + goto out; 1674 1675 /* 1676 * Allow creating a fuse mount with an already initialized fuse ··· 1668 } else { 1669 err = get_tree_nodev(fsc, fuse_fill_super); 1670 } 1671 + out: 1672 + if (fsc->s_fs_info) 1673 + fuse_mount_destroy(fm); 1674 if (ctx->file) 1675 fput(ctx->file); 1676 return err; ··· 1747 struct fuse_mount *fm = get_fuse_mount_super(sb); 1748 bool last; 1749 1750 + if (sb->s_root) { 1751 last = fuse_mount_remove(fm); 1752 if (last) 1753 fuse_conn_destroy(fm); 1754 } 1755 } 1756 1757 + void fuse_mount_destroy(struct fuse_mount *fm) 1758 + { 1759 + fuse_conn_put(fm->fc); 1760 + kfree(fm); 1761 + } 1762 + EXPORT_SYMBOL(fuse_mount_destroy); 1763 + 1764 static void fuse_kill_sb_anon(struct super_block *sb) 1765 { 1766 fuse_sb_destroy(sb); 1767 kill_anon_super(sb); 1768 + fuse_mount_destroy(get_fuse_mount_super(sb)); 1769 } 1770 1771 static struct file_system_type fuse_fs_type = { ··· 1775 { 1776 fuse_sb_destroy(sb); 1777 kill_block_super(sb); 1778 + fuse_mount_destroy(get_fuse_mount_super(sb)); 1779 } 1780 1781 static struct file_system_type fuseblk_fs_type = {
+4 -8
fs/fuse/virtio_fs.c
··· 1394 bool last; 1395 1396 /* If mount failed, we can still be called without any fc */ 1397 - if (fm) { 1398 last = fuse_mount_remove(fm); 1399 if (last) 1400 virtio_fs_conn_destroy(fm); 1401 } 1402 kill_anon_super(sb); 1403 } 1404 1405 static int virtio_fs_test_super(struct super_block *sb, ··· 1456 1457 fsc->s_fs_info = fm; 1458 sb = sget_fc(fsc, virtio_fs_test_super, set_anon_super_fc); 1459 - if (fsc->s_fs_info) { 1460 - fuse_conn_put(fc); 1461 - kfree(fm); 1462 - } 1463 if (IS_ERR(sb)) 1464 return PTR_ERR(sb); 1465 1466 if (!sb->s_root) { 1467 err = virtio_fs_fill_super(sb, fsc); 1468 if (err) { 1469 - fuse_conn_put(fc); 1470 - kfree(fm); 1471 - sb->s_fs_info = NULL; 1472 deactivate_locked_super(sb); 1473 return err; 1474 }
··· 1394 bool last; 1395 1396 /* If mount failed, we can still be called without any fc */ 1397 + if (sb->s_root) { 1398 last = fuse_mount_remove(fm); 1399 if (last) 1400 virtio_fs_conn_destroy(fm); 1401 } 1402 kill_anon_super(sb); 1403 + fuse_mount_destroy(fm); 1404 } 1405 1406 static int virtio_fs_test_super(struct super_block *sb, ··· 1455 1456 fsc->s_fs_info = fm; 1457 sb = sget_fc(fsc, virtio_fs_test_super, set_anon_super_fc); 1458 + if (fsc->s_fs_info) 1459 + fuse_mount_destroy(fm); 1460 if (IS_ERR(sb)) 1461 return PTR_ERR(sb); 1462 1463 if (!sb->s_root) { 1464 err = virtio_fs_fill_super(sb, fsc); 1465 if (err) { 1466 deactivate_locked_super(sb); 1467 return err; 1468 }