Patch "usb: gadget: configfs: Restrict symlink creation is UDC already binded" has been added to the 6.1-stable tree

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

 



This is a note to let you know that I've just added the patch titled

    usb: gadget: configfs: Restrict symlink creation is UDC already binded

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     usb-gadget-configfs-restrict-symlink-creation-is-udc.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 369c9ad69ec927bd84f90b7d536cedd19a7d8d1f
Author: Udipto Goswami <quic_ugoswami@xxxxxxxxxxx>
Date:   Wed Feb 1 18:53:08 2023 +0530

    usb: gadget: configfs: Restrict symlink creation is UDC already binded
    
    [ Upstream commit 89e7252d6c7e7eeb31971cd7df987316ecc64ff5 ]
    
    During enumeration or composition switch,a userspace process
    agnostic of the conventions of configs can try to create function
    symlinks even after the UDC is bound to current config which is
    not correct. Potentially it can create duplicates within the
    current config.
    
    Prevent this by adding a check if udc_name already exists, then bail
    out of cfg_link.
    
    Following is an example:
    
    Step1:
    ln -s X1 ffs.a
    -->cfg_link
    --> usb_get_function(ffs.a)
            ->ffs_alloc
    
            CFG->FUNC_LIST: <ffs.a>
            C->FUNCTION: <empty>
    
    Step2:
    echo udc.name > /config/usb_gadget/g1/UDC
    --> UDC_store
            ->composite_bind
            ->usb_add_function
    
            CFG->FUNC_LIST: <empty>
            C->FUNCTION: <ffs.a>
    
    Step3:
    ln -s Y1 ffs.a
    -->cfg_link
    -->usb_get_function(ffs.a)
            ->ffs_alloc
    
            CFG->FUNC_LIST: <ffs.a>
            C->FUNCTION: <ffs.a>
    
    both the lists corresponds to the same function instance ffs.a
    but the usb_function* pointer is different because in step 3
    ffs_alloc has created a new reference to usb_function* for
    ffs.a and added it to cfg_list.
    
    Step4:
    Now a composition switch involving <ffs.b,ffs.a> is executed.
    
    the composition switch will involve 3 things:
            1. unlinking the previous functions existing
            2. creating new symlinks
            3. writing UDC
    
    However, the composition switch is generally taken care by
    userspace process which creates the symlinks in its own
    nomenclature(X*) and removes only those.
    So it won't be able to remove Y1 which user had created
    by own.
    
    Due to this the new symlinks cannot be created for ffs.a
    since the entry already exists in CFG->FUNC_LIST.
    
    The state of the CFG->FUNC_LIST is as follows:
            CFG->FUNC_LIST: <ffs.a>
    
    Fixes: 88af8bbe4ef7 ("usb: gadget: the start of the configfs interface")
    Signed-off-by: Krishna Kurapati PSSNV <quic_kriskura@xxxxxxxxxxx>
    Signed-off-by: Udipto Goswami <quic_ugoswami@xxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20230201132308.31523-1-quic_ugoswami@xxxxxxxxxxx
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 7bbc776185469..4dcf29577f8f1 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -429,6 +429,12 @@ static int config_usb_cfg_link(
 	 * from another gadget or a random directory.
 	 * Also a function instance can only be linked once.
 	 */
+
+	if (gi->composite.gadget_driver.udc_name) {
+		ret = -EINVAL;
+		goto out;
+	}
+
 	list_for_each_entry(iter, &gi->available_func, cfs_list) {
 		if (iter != fi)
 			continue;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux