Skip to content

Commit e4172c5

Browse files
Guanghui Fengjoergroedel
authored andcommitted
iommu/amd: Fix illegal device-id access in IOMMU debugfs
In the current AMD IOMMU debugFS, when multiple processes use the IOMMU debugFS process simultaneously, illegal access issues can occur in the following execution flow: 1. CPU1: Sets a valid sbdf via devid_write, then checks the sbdf's validity in execution flows such as devid_show, iommu_devtbl_show, and iommu_irqtbl_show. 2. CPU2: Sets an invalid sbdf via devid_write, at which point the sbdf value is -1. 3. CPU1: accesses the IOMMU device table, IRQ table, based on the invalid SBDF value of -1, resulting in illegal access. This is especially problematic in monitoring scripts, where multiple scripts may access debugFS simultaneously, and some scripts may unexpectedly set invalid values, which triggers illegal access in debugfs. This patch modifies the execution flow of devid_show, iommu_devtbl_show, and iommu_irqtbl_show to ensure that these processes determine the validity and access based on the same device-id, thus guaranteeing correctness and robustness. Signed-off-by: Guanghui Feng <guanghuifeng@linux.alibaba.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
1 parent 1e0c8d6 commit e4172c5

1 file changed

Lines changed: 12 additions & 9 deletions

File tree

drivers/iommu/amd/debugfs.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,11 @@ static ssize_t devid_write(struct file *filp, const char __user *ubuf,
197197
static int devid_show(struct seq_file *m, void *unused)
198198
{
199199
u16 devid;
200+
int sbdf_shadow = sbdf;
200201

201-
if (sbdf >= 0) {
202-
devid = PCI_SBDF_TO_DEVID(sbdf);
203-
seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf),
202+
if (sbdf_shadow >= 0) {
203+
devid = PCI_SBDF_TO_DEVID(sbdf_shadow);
204+
seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf_shadow),
204205
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid));
205206
} else
206207
seq_puts(m, "No or Invalid input provided\n");
@@ -237,13 +238,14 @@ static int iommu_devtbl_show(struct seq_file *m, void *unused)
237238
{
238239
struct amd_iommu_pci_seg *pci_seg;
239240
u16 seg, devid;
241+
int sbdf_shadow = sbdf;
240242

241-
if (sbdf < 0) {
243+
if (sbdf_shadow < 0) {
242244
seq_puts(m, "Enter a valid device ID to 'devid' file\n");
243245
return 0;
244246
}
245-
seg = PCI_SBDF_TO_SEGID(sbdf);
246-
devid = PCI_SBDF_TO_DEVID(sbdf);
247+
seg = PCI_SBDF_TO_SEGID(sbdf_shadow);
248+
devid = PCI_SBDF_TO_DEVID(sbdf_shadow);
247249

248250
for_each_pci_segment(pci_seg) {
249251
if (pci_seg->id != seg)
@@ -336,19 +338,20 @@ static int iommu_irqtbl_show(struct seq_file *m, void *unused)
336338
{
337339
struct amd_iommu_pci_seg *pci_seg;
338340
u16 devid, seg;
341+
int sbdf_shadow = sbdf;
339342

340343
if (!irq_remapping_enabled) {
341344
seq_puts(m, "Interrupt remapping is disabled\n");
342345
return 0;
343346
}
344347

345-
if (sbdf < 0) {
348+
if (sbdf_shadow < 0) {
346349
seq_puts(m, "Enter a valid device ID to 'devid' file\n");
347350
return 0;
348351
}
349352

350-
seg = PCI_SBDF_TO_SEGID(sbdf);
351-
devid = PCI_SBDF_TO_DEVID(sbdf);
353+
seg = PCI_SBDF_TO_SEGID(sbdf_shadow);
354+
devid = PCI_SBDF_TO_DEVID(sbdf_shadow);
352355

353356
for_each_pci_segment(pci_seg) {
354357
if (pci_seg->id != seg)

0 commit comments

Comments
 (0)