{
   "containers": {
      "cna": {
         "providerMetadata": {
            "orgId": "f4215fc3-5b6b-47ff-a258-f7189bd81038"
         },
         "descriptions": [
            {
               "lang": "en",
               "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)."
            }
         ],
         "affected": [
            {
               "product": "Linux",
               "vendor": "Linux",
               "defaultStatus": "unaffected",
               "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
               "programFiles": [
                  "drivers/iommu/intel/dmar.c"
               ],
               "versions": [
                  {
                     "version": "1da177e4c3f4",
                     "lessThan": "de9e7f687625",
                     "status": "affected",
                     "versionType": "git"
                  },
                  {
                     "version": "1da177e4c3f4",
                     "lessThan": "8840dc73ac9e",
                     "status": "affected",
                     "versionType": "git"
                  },
                  {
                     "version": "1da177e4c3f4",
                     "lessThan": "e03f00aa4a6c",
                     "status": "affected",
                     "versionType": "git"
                  },
                  {
                     "version": "1da177e4c3f4",
                     "lessThan": "dfdbc5ba10fb",
                     "status": "affected",
                     "versionType": "git"
                  },
                  {
                     "version": "1da177e4c3f4",
                     "lessThan": "07e4e92f84b7",
                     "status": "affected",
                     "versionType": "git"
                  },
                  {
                     "version": "1da177e4c3f4",
                     "lessThan": "92ba5b014d54",
                     "status": "affected",
                     "versionType": "git"
                  },
                  {
                     "version": "1da177e4c3f4",
                     "lessThan": "3cf74230c139",
                     "status": "affected",
                     "versionType": "git"
                  }
               ]
            },
            {
               "product": "Linux",
               "vendor": "Linux",
               "defaultStatus": "affected",
               "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
               "programFiles": [
                  "drivers/iommu/intel/dmar.c"
               ],
               "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"
                  }
               ]
            }
         ],
         "references": [
            {
               "url": "https://git.kernel.org/stable/c/de9e7f68762585f7532de8a06de9485bf39dbd38"
            },
            {
               "url": "https://git.kernel.org/stable/c/8840dc73ac9e1028291458ef1429ec3c2524ffec"
            },
            {
               "url": "https://git.kernel.org/stable/c/e03f00aa4a6c0c49c17857a4048f586636abdc32"
            },
            {
               "url": "https://git.kernel.org/stable/c/dfdbc5ba10fb792c9d6d12ba8cb6e465f97365ed"
            },
            {
               "url": "https://git.kernel.org/stable/c/07e4e92f84b7d3018b7064ef8d8438aeb54a2ca5"
            },
            {
               "url": "https://git.kernel.org/stable/c/92ba5b014d5435dd7a1ee02a2c7f2a0e8fe06c36"
            },
            {
               "url": "https://git.kernel.org/stable/c/3cf74230c139f208b7fb313ae0054386eee31a81"
            }
         ],
         "title": "iommu/vt-d: Fix potential lockup if qi_submit_sync called with 0 count",
         "x_generator": {
            "engine": "bippy-c9c4e1df01b2"
         }
      }
   },
   "cveMetadata": {
      "assignerOrgId": "f4215fc3-5b6b-47ff-a258-f7189bd81038",
      "cveID": "CVE-2024-49993",
      "requesterUserId": "gregkh@kernel.org",
      "serial": "1",
      "state": "PUBLISHED"
   },
   "dataType": "CVE_RECORD",
   "dataVersion": "5.0"
}
