On Thu, Aug 15, 2024 at 03:11:17PM -0300, Jason Gunthorpe wrote:
On Wed, Aug 07, 2024 at 01:10:42PM -0700, Nicolin Chen wrote:
+int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd) +{
- struct iommu_viommu_alloc *cmd = ucmd->cmd;
- struct iommufd_hwpt_paging *hwpt_paging;
- struct iommufd_viommu *viommu;
- struct iommufd_device *idev;
- int rc;
- if (cmd->flags)
return -EOPNOTSUPP;
- idev = iommufd_get_device(ucmd, cmd->dev_id);
- if (IS_ERR(idev))
return PTR_ERR(idev);
- hwpt_paging = iommufd_get_hwpt_paging(ucmd, cmd->hwpt_id);
- if (IS_ERR(hwpt_paging)) {
rc = PTR_ERR(hwpt_paging);
goto out_put_idev;
- }
- if (!hwpt_paging->nest_parent) {
rc = -EINVAL;
goto out_put_hwpt;
- }
- if (cmd->type != IOMMU_VIOMMU_TYPE_DEFAULT) {
rc = -EOPNOTSUPP;
goto out_put_hwpt;
- }
- viommu = iommufd_object_alloc(ucmd->ictx, viommu, IOMMUFD_OBJ_VIOMMU);
- if (IS_ERR(viommu)) {
rc = PTR_ERR(viommu);
goto out_put_hwpt;
- }
- viommu->type = cmd->type;
- viommu->ictx = ucmd->ictx;
- viommu->hwpt = hwpt_paging;
- viommu->iommu_dev = idev->dev->iommu->iommu_dev;
Pedantically this is troublesome because we don't have any lifetime control on this pointer.
iommu unplug is fairly troubled on real HW, but the selftest does do it.
At least for this series the value isn't used so lets remove it.
I recall one of my local versions had a validation using that, but not that crucial either. Will drop it.
I don't have an easy solution in mind though later as surely we will need this when we start to create more iommu bound objects. I'm pretty sure syzkaller would eventually find such a UAF using the iommufd selftest framework.
Would adding a user count in struct iommu_device help?
Thanks Nicolin