{
    "data_version": "4.0",
    "data_type": "CVE",
    "data_format": "MITRE",
    "CVE_data_meta": {
        "ID": "CVE-2024-49993",
        "ASSIGNER": "cve@kernel.org",
        "STATE": "PUBLIC"
    },
    "description": {
        "description_data": [
            {
                "lang": "eng",
                "value": "In the Linux kernel, the following vulnerability has been resolved:\n\niommu/vt-d: Fix potential lockup if qi_submit_sync called with 0 count\n\nIf qi_submit_sync() is invoked with 0 invalidation descriptors (for\ninstance, for DMA draining purposes), we can run into a bug where a\nsubmitting thread fails to detect the completion of invalidation_wait.\nSubsequently, this led to a soft lockup. Currently, there is no impact\nby this bug on the existing users because no callers are submitting\ninvalidations with 0 descriptors. This fix will enable future users\n(such as DMA drain) calling qi_submit_sync() with 0 count.\n\nSuppose thread T1 invokes qi_submit_sync() with non-zero descriptors, while\nconcurrently, thread T2 calls qi_submit_sync() with zero descriptors. Both\nthreads then enter a while loop, waiting for their respective descriptors\nto complete. T1 detects its completion (i.e., T1's invalidation_wait status\nchanges to QI_DONE by HW) and proceeds to call reclaim_free_desc() to\nreclaim all descriptors, potentially including adjacent ones of other\nthreads that are also marked as QI_DONE.\n\nDuring this time, while T2 is waiting to acquire the qi->q_lock, the IOMMU\nhardware may complete the invalidation for T2, setting its status to\nQI_DONE. However, if T1's execution of reclaim_free_desc() frees T2's\ninvalidation_wait descriptor and changes its status to QI_FREE, T2 will\nnot observe the QI_DONE status for its invalidation_wait and will\nindefinitely remain stuck.\n\nThis soft lockup does not occur when only non-zero descriptors are\nsubmitted.In such cases, invalidation descriptors are interspersed among\nwait descriptors with the status QI_IN_USE, acting as barriers. These\nbarriers prevent the reclaim code from mistakenly freeing descriptors\nbelonging to other submitters.\n\nConsidered the following example timeline:\n\tT1\t\t\tT2\n========================================\n\tID1\n\tWD1\n\twhile(WD1!=QI_DONE)\n\tunlock\n\t\t\t\tlock\n\tWD1=QI_DONE*\t\tWD2\n\t\t\t\twhile(WD2!=QI_DONE)\n\t\t\t\tunlock\n\tlock\n\tWD1==QI_DONE?\n\tID1=QI_DONE\t\tWD2=DONE*\n\treclaim()\n\tID1=FREE\n\tWD1=FREE\n\tWD2=FREE\n\tunlock\n\t\t\t\tsoft lockup! T2 never sees QI_DONE in WD2\n\nWhere:\nID = invalidation descriptor\nWD = wait descriptor\n* Written by hardware\n\nThe root of the problem is that the descriptor status QI_DONE flag is used\nfor two conflicting purposes:\n1. signal a descriptor is ready for reclaim (to be freed)\n2. signal by the hardware that a wait descriptor is complete\n\nThe solution (in this patch) is state separation by using QI_FREE flag\nfor #1.\n\nOnce a thread's invalidation descriptors are complete, their status would\nbe set to QI_FREE. The reclaim_free_desc() function would then only\nfree descriptors marked as QI_FREE instead of those marked as\nQI_DONE. This change ensures that T2 (from the previous example) will\ncorrectly observe the completion of its invalidation_wait (marked as\nQI_DONE)."
            }
        ]
    },
    "problemtype": {
        "problemtype_data": [
            {
                "description": [
                    {
                        "lang": "eng",
                        "value": "n/a"
                    }
                ]
            }
        ]
    },
    "affects": {
        "vendor": {
            "vendor_data": [
                {
                    "vendor_name": "Linux",
                    "product": {
                        "product_data": [
                            {
                                "product_name": "Linux",
                                "version": {
                                    "version_data": [
                                        {
                                            "version_affected": "<",
                                            "version_name": "1da177e4c3f4",
                                            "version_value": "de9e7f687625"
                                        },
                                        {
                                            "version_value": "not down converted",
                                            "x_cve_json_5_version_data": {
                                                "versions": [
                                                    {
                                                        "version": "5.10.227",
                                                        "lessThanOrEqual": "5.10.*",
                                                        "status": "unaffected",
                                                        "versionType": "custom"
                                                    },
                                                    {
                                                        "version": "5.15.168",
                                                        "lessThanOrEqual": "5.15.*",
                                                        "status": "unaffected",
                                                        "versionType": "custom"
                                                    },
                                                    {
                                                        "version": "6.1.113",
                                                        "lessThanOrEqual": "6.1.*",
                                                        "status": "unaffected",
                                                        "versionType": "custom"
                                                    },
                                                    {
                                                        "version": "6.6.55",
                                                        "lessThanOrEqual": "6.6.*",
                                                        "status": "unaffected",
                                                        "versionType": "custom"
                                                    },
                                                    {
                                                        "version": "6.10.14",
                                                        "lessThanOrEqual": "6.10.*",
                                                        "status": "unaffected",
                                                        "versionType": "custom"
                                                    },
                                                    {
                                                        "version": "6.11.3",
                                                        "lessThanOrEqual": "6.11.*",
                                                        "status": "unaffected",
                                                        "versionType": "custom"
                                                    },
                                                    {
                                                        "version": "6.12-rc1",
                                                        "lessThanOrEqual": "*",
                                                        "status": "unaffected",
                                                        "versionType": "original_commit_for_fix"
                                                    }
                                                ],
                                                "defaultStatus": "affected"
                                            }
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }
            ]
        }
    },
    "references": {
        "reference_data": [
            {
                "url": "https://git.kernel.org/stable/c/de9e7f68762585f7532de8a06de9485bf39dbd38",
                "refsource": "MISC",
                "name": "https://git.kernel.org/stable/c/de9e7f68762585f7532de8a06de9485bf39dbd38"
            },
            {
                "url": "https://git.kernel.org/stable/c/8840dc73ac9e1028291458ef1429ec3c2524ffec",
                "refsource": "MISC",
                "name": "https://git.kernel.org/stable/c/8840dc73ac9e1028291458ef1429ec3c2524ffec"
            },
            {
                "url": "https://git.kernel.org/stable/c/e03f00aa4a6c0c49c17857a4048f586636abdc32",
                "refsource": "MISC",
                "name": "https://git.kernel.org/stable/c/e03f00aa4a6c0c49c17857a4048f586636abdc32"
            },
            {
                "url": "https://git.kernel.org/stable/c/dfdbc5ba10fb792c9d6d12ba8cb6e465f97365ed",
                "refsource": "MISC",
                "name": "https://git.kernel.org/stable/c/dfdbc5ba10fb792c9d6d12ba8cb6e465f97365ed"
            },
            {
                "url": "https://git.kernel.org/stable/c/07e4e92f84b7d3018b7064ef8d8438aeb54a2ca5",
                "refsource": "MISC",
                "name": "https://git.kernel.org/stable/c/07e4e92f84b7d3018b7064ef8d8438aeb54a2ca5"
            },
            {
                "url": "https://git.kernel.org/stable/c/92ba5b014d5435dd7a1ee02a2c7f2a0e8fe06c36",
                "refsource": "MISC",
                "name": "https://git.kernel.org/stable/c/92ba5b014d5435dd7a1ee02a2c7f2a0e8fe06c36"
            },
            {
                "url": "https://git.kernel.org/stable/c/3cf74230c139f208b7fb313ae0054386eee31a81",
                "refsource": "MISC",
                "name": "https://git.kernel.org/stable/c/3cf74230c139f208b7fb313ae0054386eee31a81"
            }
        ]
    },
    "generator": {
        "engine": "bippy-c9c4e1df01b2"
    }
}