qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] qdev: Reject duplicate and anti-social device IDs


From: Markus Armbruster
Subject: [Qemu-devel] [PATCH] qdev: Reject duplicate and anti-social device IDs
Date: Mon, 31 May 2010 16:13:12 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)

We need Device IDs to be unique and not contain '/' so device tree
nodes can always be unambigously referenced by tree path.

We already have some protection against duplicate IDs, but it got
holes:

* We don't assign IDs to default devices.

* -device and device_add use the ID of a qemu_device_opts.  Which
  rejects duplicate IDs.

* pci_add nic -net use either the ID or option "name" of
  qemu_net_opts.  And there's our hole.  Reproducible with "-net user
  -net nic,id=foo -device lsi,id=foo".

Also require IDs to start with a letter to provide for possible future
extensions.

Signed-off-by: Markus Armbruster <address@hidden>
---
Note: If requiring IDs to start with a letter should turn out to be
controversial, I'm happy to respin without that part.

 hw/qdev.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index af17486..877cdf4 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -40,6 +40,7 @@ DeviceInfo *device_info_list;
 static BusState *qbus_find_recursive(BusState *bus, const char *name,
                                      const BusInfo *info);
 static BusState *qbus_find(const char *path);
+static DeviceState *qdev_find_recursive(BusState *bus, const char *id);
 
 /* Register a new device type.  */
 void qdev_register(DeviceInfo *info)
@@ -242,6 +243,16 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     qdev = qdev_create_from_info(bus, info);
     id = qemu_opts_id(opts);
     if (id) {
+        if (!qemu_isalpha(id[0]) || strchr(id, '/')) {
+            qerror_report(QERR_INVALID_PARAMETER_VALUE, "id",
+                          "an identifier starting with a letter, "
+                          "and not containing '/'");
+            return NULL;
+        }
+        if (qdev_find_recursive(main_system_bus, id)) {
+            qerror_report(QERR_DUPLICATE_ID, id, "device");
+            return NULL;
+        }
         qdev->id = id;
     }
     if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
-- 
1.6.6.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]