[libvirt] [PATCH 02/20] pci: Remove PATH_MAX sized stack allocations

Matthias Bolte matthias.bolte at googlemail.com
Sun Apr 3 09:21:15 UTC 2011


Use virAsprintf instead of snprintf.
---
 src/util/pci.c |  172 +++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 127 insertions(+), 45 deletions(-)

diff --git a/src/util/pci.c b/src/util/pci.c
index 8d2dbb0..6ed96f4 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -775,38 +775,72 @@ pciResetDevice(pciDevice *dev,
 }
 
 
-static void
-pciDriverDir(char *buf, size_t buflen, const char *driver)
+static int
+pciDriverDir(char **buffer, const char *driver)
 {
-    snprintf(buf, buflen, PCI_SYSFS "drivers/%s", driver);
+    VIR_FREE(*buffer);
+
+    if (virAsprintf(buffer, PCI_SYSFS "drivers/%s", driver) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    return 0;
 }
 
-static void
-pciDriverFile(char *buf, size_t buflen, const char *driver, const char *file)
+static int
+pciDriverFile(char **buffer, const char *driver, const char *file)
 {
-    snprintf(buf, buflen, PCI_SYSFS "drivers/%s/%s", driver, file);
+    VIR_FREE(*buffer);
+
+    if (virAsprintf(buffer, PCI_SYSFS "drivers/%s/%s", driver, file) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    return 0;
 }
 
-static void
-pciDeviceFile(char *buf, size_t buflen, const char *device, const char *file)
+static int
+pciDeviceFile(char **buffer, const char *device, const char *file)
 {
-    snprintf(buf, buflen, PCI_SYSFS "devices/%s/%s", device, file);
+    VIR_FREE(*buffer);
+
+    if (virAsprintf(buffer, PCI_SYSFS "devices/%s/%s", device, file) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    return 0;
 }
 
 
 static const char *
 pciFindStubDriver(void)
 {
-    char drvpath[PATH_MAX];
+    char *drvpath = NULL;
     int probed = 0;
 
 recheck:
-    pciDriverDir(drvpath, sizeof(drvpath), "pci-stub");
-    if (virFileExists(drvpath))
+    if (pciDriverDir(&drvpath, "pci-stub") < 0) {
+        return NULL;
+    }
+
+    if (virFileExists(drvpath)) {
+        VIR_FREE(drvpath);
         return "pci-stub";
-    pciDriverDir(drvpath, sizeof(drvpath), "pciback");
-    if (virFileExists(drvpath))
+    }
+
+    if (pciDriverDir(&drvpath, "pciback") < 0) {
+        return NULL;
+    }
+
+    if (virFileExists(drvpath)) {
+        VIR_FREE(drvpath);
         return "pciback";
+    }
+
+    VIR_FREE(drvpath);
 
     if (!probed) {
         const char *const stubprobe[] = { MODPROBE, "pci-stub", NULL };
@@ -837,8 +871,9 @@ recheck:
 static int
 pciBindDeviceToStub(pciDevice *dev, const char *driver)
 {
-    char drvdir[PATH_MAX];
-    char path[PATH_MAX];
+    int result = -1;
+    char *drvdir = NULL;
+    char *path = NULL;
 
     /* Add the PCI device ID to the stub's dynamic ID table;
      * this is needed to allow us to bind the device to the stub.
@@ -848,12 +883,15 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
      * is triggered for such a device, it will also be immediately
      * bound by the stub.
      */
-    pciDriverFile(path, sizeof(path), driver, "new_id");
+    if (pciDriverFile(&path, driver, "new_id") < 0) {
+        return -1;
+    }
+
     if (virFileWriteStr(path, dev->id, 0) < 0) {
         virReportSystemError(errno,
                              _("Failed to add PCI device ID '%s' to %s"),
                              dev->id, driver);
-        return -1;
+        goto cleanup;
     }
 
     /* If the device is already bound to a driver, unbind it.
@@ -861,48 +899,69 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
      * PCI device happens to be IDE controller for the disk hosting
      * your root filesystem.
      */
-    pciDeviceFile(path, sizeof(path), dev->name, "driver/unbind");
+    if (pciDeviceFile(&path, dev->name, "driver/unbind") < 0) {
+        goto cleanup;
+    }
+
     if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) {
         virReportSystemError(errno,
                              _("Failed to unbind PCI device '%s'"), dev->name);
-        return -1;
+        goto cleanup;
     }
 
     /* If the device isn't already bound to pci-stub, try binding it now.
      */
-    pciDriverDir(drvdir, sizeof(drvdir), driver);
-    pciDeviceFile(path, sizeof(path), dev->name, "driver");
+    if (pciDriverDir(&drvdir, driver) < 0 ||
+        pciDeviceFile(&path, dev->name, "driver") < 0) {
+        goto cleanup;
+    }
+
     if (!virFileLinkPointsTo(path, drvdir)) {
         /* Xen's pciback.ko wants you to use new_slot first */
-        pciDriverFile(path, sizeof(path), driver, "new_slot");
+        if (pciDriverFile(&path, driver, "new_slot") < 0) {
+            goto cleanup;
+        }
+
         if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) {
             virReportSystemError(errno,
                                  _("Failed to add slot for PCI device '%s' to %s"),
                                  dev->name, driver);
-            return -1;
+            goto cleanup;
+        }
+
+        if (pciDriverFile(&path, driver, "bind") < 0) {
+            goto cleanup;
         }
 
-        pciDriverFile(path, sizeof(path), driver, "bind");
         if (virFileWriteStr(path, dev->name, 0) < 0) {
             virReportSystemError(errno,
                                  _("Failed to bind PCI device '%s' to %s"),
                                  dev->name, driver);
-            return -1;
+            goto cleanup;
         }
     }
 
     /* If 'remove_id' exists, remove the device id from pci-stub's dynamic
      * ID table so that 'drivers_probe' works below.
      */
-    pciDriverFile(path, sizeof(path), driver, "remove_id");
+    if (pciDriverFile(&path, driver, "remove_id") < 0) {
+        goto cleanup;
+    }
+
     if (virFileExists(path) && virFileWriteStr(path, dev->id, 0) < 0) {
         virReportSystemError(errno,
                              _("Failed to remove PCI ID '%s' from %s"),
                              dev->id, driver);
-        return -1;
+        goto cleanup;
     }
 
-    return 0;
+    result = 0;
+
+cleanup:
+    VIR_FREE(drvdir);
+    VIR_FREE(path);
+
+    return result;
 }
 
 int
@@ -927,49 +986,67 @@ pciDettachDevice(pciDevice *dev, pciDeviceList *activeDevs)
 static int
 pciUnBindDeviceFromStub(pciDevice *dev, const char *driver)
 {
-    char drvdir[PATH_MAX];
-    char path[PATH_MAX];
+    int result = -1;
+    char *drvdir = NULL;
+    char *path = NULL;
 
     /* If the device is bound to stub, unbind it.
      */
-    pciDriverDir(drvdir, sizeof(drvdir), driver);
-    pciDeviceFile(path, sizeof(path), dev->name, "driver");
+    if (pciDriverDir(&drvdir, driver) < 0 ||
+        pciDeviceFile(&path, dev->name, "driver") < 0) {
+        goto cleanup;
+    }
+
     if (virFileExists(drvdir) && virFileLinkPointsTo(path, drvdir)) {
-        pciDriverFile(path, sizeof(path), driver, "unbind");
+        if (pciDriverFile(&path, driver, "unbind") < 0) {
+            goto cleanup;
+        }
+
         if (virFileWriteStr(path, dev->name, 0) < 0) {
             virReportSystemError(errno,
                                  _("Failed to bind PCI device '%s' to %s"),
                                  dev->name, driver);
-            return -1;
+            goto cleanup;
         }
     }
 
     /* Xen's pciback.ko wants you to use remove_slot on the specific device */
-    pciDriverFile(path, sizeof(path), driver, "remove_slot");
+    if (pciDriverFile(&path, driver, "remove_slot") < 0) {
+        goto cleanup;
+    }
+
     if (virFileExists(path) && virFileWriteStr(path, dev->name, 0) < 0) {
         virReportSystemError(errno,
                              _("Failed to remove slot for PCI device '%s' to %s"),
                              dev->name, driver);
-        return -1;
+        goto cleanup;
     }
 
-
     /* Trigger a re-probe of the device is not in the stub's dynamic
      * ID table. If the stub is available, but 'remove_id' isn't
      * available, then re-probing would just cause the device to be
      * re-bound to the stub.
      */
-    pciDriverFile(path, sizeof(path), driver, "remove_id");
+    if (pciDriverFile(&path, driver, "remove_id") < 0) {
+        goto cleanup;
+    }
+
     if (!virFileExists(drvdir) || virFileExists(path)) {
         if (virFileWriteStr(PCI_SYSFS "drivers_probe", dev->name, 0) < 0) {
             virReportSystemError(errno,
                                  _("Failed to trigger a re-probe for PCI device '%s'"),
                                  dev->name);
-            return -1;
+            goto cleanup;
         }
     }
 
-    return 0;
+    result = 0;
+
+cleanup:
+    VIR_FREE(drvdir);
+    VIR_FREE(path);
+
+    return result;
 }
 
 int
@@ -1103,15 +1180,20 @@ pciWaitForDeviceCleanup(pciDevice *dev, const char *matcher)
 static char *
 pciReadDeviceID(pciDevice *dev, const char *id_name)
 {
-    char path[PATH_MAX];
+    char *path;
     char *id_str;
 
-    snprintf(path, sizeof(path), PCI_SYSFS "devices/%s/%s",
-             dev->name, id_name);
+    if (pciDeviceFile(&path, dev->name, id_name) < 0) {
+        return NULL;
+    }
 
     /* ID string is '0xNNNN\n' ... i.e. 7 bytes */
-    if (virFileReadAll(path, 7, &id_str) < 0)
+    if (virFileReadAll(path, 7, &id_str) < 0) {
+        VIR_FREE(path);
         return NULL;
+    }
+
+    VIR_FREE(path);
 
     /* Check for 0x suffix */
     if (id_str[0] != '0' || id_str[1] != 'x') {
-- 
1.7.0.4




More information about the libvir-list mailing list