]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
USB: class: CDC-ACM: fix race between get_serial and set_serial
authorOliver Neukum <oneukum@suse.com>
Thu, 12 Sep 2024 14:19:06 +0000 (16:19 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 13 Sep 2024 05:53:52 +0000 (07:53 +0200)
TIOCGSERIAL is an ioctl. Thus it must be atomic. It returns
two values. Racing with set_serial it can return an inconsistent
result. The mutex must be taken.

In terms of logic the bug is as old as the driver. In terms of
code it goes back to the conversion to the get_serial and
set_serial methods.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Cc: stable <stable@kernel.org>
Fixes: 99f75a1fcd865 ("cdc-acm: switch to ->[sg]et_serial()")
Link: https://lore.kernel.org/r/20240912141916.1044393-1-oneukum@suse.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/class/cdc-acm.c

index 0c1b69d944ca45e77248ffcdd0efe4d59e779d7a..605fea4611029bb295f2b43ff00cad20a2659de4 100644 (file)
@@ -962,10 +962,12 @@ static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss)
        struct acm *acm = tty->driver_data;
 
        ss->line = acm->minor;
+       mutex_lock(&acm->port.mutex);
        ss->close_delay = jiffies_to_msecs(acm->port.close_delay) / 10;
        ss->closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
                                ASYNC_CLOSING_WAIT_NONE :
                                jiffies_to_msecs(acm->port.closing_wait) / 10;
+       mutex_unlock(&acm->port.mutex);
        return 0;
 }