From 2deb96b5d4bb20a33bfaf80e30f38f3433653054 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 18 Feb 2015 10:34:52 +0700 Subject: [PATCH] USB: serial: fix port attribute-creation race Fix attribute-creation race with userspace by using the port device groups field to create the port attributes. Also use %u when printing the port number, which is unsigned, even though we do not currently support more than 128 ports per device. Reported-by: Takashi Iwai Signed-off-by: Johan Hovold Acked-by: Greg Kroah-Hartman --- drivers/usb/serial/bus.c | 19 ------------------- drivers/usb/serial/usb-serial.c | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 6f91eb9ae81a..b53a28692226 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -38,15 +38,6 @@ static int usb_serial_device_match(struct device *dev, return 0; } -static ssize_t port_number_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct usb_serial_port *port = to_usb_serial_port(dev); - - return sprintf(buf, "%d\n", port->port_number); -} -static DEVICE_ATTR_RO(port_number); - static int usb_serial_device_probe(struct device *dev) { struct usb_serial_driver *driver; @@ -73,18 +64,10 @@ static int usb_serial_device_probe(struct device *dev) goto exit_with_autopm; } - retval = device_create_file(dev, &dev_attr_port_number); - if (retval) { - if (driver->port_remove) - driver->port_remove(port); - goto exit_with_autopm; - } - minor = port->minor; tty_dev = tty_register_device(usb_serial_tty_driver, minor, dev); if (IS_ERR(tty_dev)) { retval = PTR_ERR(tty_dev); - device_remove_file(dev, &dev_attr_port_number); if (driver->port_remove) driver->port_remove(port); goto exit_with_autopm; @@ -123,8 +106,6 @@ static int usb_serial_device_remove(struct device *dev) minor = port->minor; tty_unregister_device(usb_serial_tty_driver, minor); - device_remove_file(&port->dev, &dev_attr_port_number); - driver = port->serial->type; if (driver->port_remove) retval = driver->port_remove(port); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 19842370a07f..529066bbc7e8 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -687,6 +687,21 @@ static void serial_port_dtr_rts(struct tty_port *port, int on) drv->dtr_rts(p, on); } +static ssize_t port_number_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_serial_port *port = to_usb_serial_port(dev); + + return sprintf(buf, "%u\n", port->port_number); +} +static DEVICE_ATTR_RO(port_number); + +static struct attribute *usb_serial_port_attrs[] = { + &dev_attr_port_number.attr, + NULL +}; +ATTRIBUTE_GROUPS(usb_serial_port); + static const struct tty_port_operations serial_port_ops = { .carrier_raised = serial_port_carrier_raised, .dtr_rts = serial_port_dtr_rts, @@ -902,6 +917,7 @@ static int usb_serial_probe(struct usb_interface *interface, port->dev.driver = NULL; port->dev.bus = &usb_serial_bus_type; port->dev.release = &usb_serial_port_release; + port->dev.groups = usb_serial_port_groups; device_initialize(&port->dev); } -- 2.11.0