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 <arm...@redhat.com> --- 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