From: Greg Kroah-Hartman Date: Sun, 11 Apr 2021 07:26:10 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.19.187~53 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e16714769e29435b7a2ab9fbcab38d1826418683;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: driver-core-fix-locking-bug-in-deferred_probe_timeout_work_func.patch i2c-turn-recovery-error-on-init-to-debug.patch percpu-make-pcpu_nr_empty_pop_pages-per-chunk-type.patch scsi-pm80xx-fix-chip-initialization-failure.patch scsi-target-iscsi-fix-zero-tag-inside-a-trace-event.patch thunderbolt-fix-a-leak-in-tb_retimer_add.patch thunderbolt-fix-off-by-one-in-tb_port_find_retimer.patch usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch usbip-stub-dev-synchronize-sysfs-code-paths.patch usbip-synchronize-event-handler-with-sysfs-code-paths.patch usbip-vudc-synchronize-sysfs-code-paths.patch --- diff --git a/queue-5.10/driver-core-fix-locking-bug-in-deferred_probe_timeout_work_func.patch b/queue-5.10/driver-core-fix-locking-bug-in-deferred_probe_timeout_work_func.patch new file mode 100644 index 00000000000..b2b2a1777fd --- /dev/null +++ b/queue-5.10/driver-core-fix-locking-bug-in-deferred_probe_timeout_work_func.patch @@ -0,0 +1,45 @@ +From eed6e41813deb9ee622cd9242341f21430d7789f Mon Sep 17 00:00:00 2001 +From: Saravana Kannan +Date: Thu, 1 Apr 2021 21:03:40 -0700 +Subject: driver core: Fix locking bug in deferred_probe_timeout_work_func() + +From: Saravana Kannan + +commit eed6e41813deb9ee622cd9242341f21430d7789f upstream. + +list_for_each_entry_safe() is only useful if we are deleting nodes in a +linked list within the loop. It doesn't protect against other threads +adding/deleting nodes to the list in parallel. We need to grab +deferred_probe_mutex when traversing the deferred_probe_pending_list. + +Cc: stable@vger.kernel.org +Fixes: 25b4e70dcce9 ("driver core: allow stopping deferred probe after init") +Signed-off-by: Saravana Kannan +Link: https://lore.kernel.org/r/20210402040342.2944858-2-saravanak@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/base/dd.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/base/dd.c ++++ b/drivers/base/dd.c +@@ -292,14 +292,16 @@ int driver_deferred_probe_check_state(st + + static void deferred_probe_timeout_work_func(struct work_struct *work) + { +- struct device_private *private, *p; ++ struct device_private *p; + + driver_deferred_probe_timeout = 0; + driver_deferred_probe_trigger(); + flush_work(&deferred_probe_work); + +- list_for_each_entry_safe(private, p, &deferred_probe_pending_list, deferred_probe) +- dev_info(private->device, "deferred probe pending\n"); ++ mutex_lock(&deferred_probe_mutex); ++ list_for_each_entry(p, &deferred_probe_pending_list, deferred_probe) ++ dev_info(p->device, "deferred probe pending\n"); ++ mutex_unlock(&deferred_probe_mutex); + wake_up_all(&probe_timeout_waitqueue); + } + static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func); diff --git a/queue-5.10/i2c-turn-recovery-error-on-init-to-debug.patch b/queue-5.10/i2c-turn-recovery-error-on-init-to-debug.patch new file mode 100644 index 00000000000..11c97f3fbf1 --- /dev/null +++ b/queue-5.10/i2c-turn-recovery-error-on-init-to-debug.patch @@ -0,0 +1,53 @@ +From e409a6a3e0690efdef9b8a96197bc61ff117cfaf Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Mon, 15 Mar 2021 12:50:08 +0100 +Subject: i2c: turn recovery error on init to debug + +From: Wolfram Sang + +commit e409a6a3e0690efdef9b8a96197bc61ff117cfaf upstream. + +In some configurations, recovery is optional. So, don't throw an error +when it is not used because e.g. pinctrl settings for recovery are not +provided. Reword the message and make it debug output. + +Reported-by: Klaus Kudielka +Tested-by: Klaus Kudielka +Signed-off-by: Wolfram Sang +Signed-off-by: Wolfram Sang +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/i2c-core-base.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/i2c/i2c-core-base.c ++++ b/drivers/i2c/i2c-core-base.c +@@ -378,7 +378,7 @@ static int i2c_gpio_init_recovery(struct + static int i2c_init_recovery(struct i2c_adapter *adap) + { + struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; +- char *err_str; ++ char *err_str, *err_level = KERN_ERR; + + if (!bri) + return 0; +@@ -387,7 +387,8 @@ static int i2c_init_recovery(struct i2c_ + return -EPROBE_DEFER; + + if (!bri->recover_bus) { +- err_str = "no recover_bus() found"; ++ err_str = "no suitable method provided"; ++ err_level = KERN_DEBUG; + goto err; + } + +@@ -414,7 +415,7 @@ static int i2c_init_recovery(struct i2c_ + + return 0; + err: +- dev_err(&adap->dev, "Not using recovery: %s\n", err_str); ++ dev_printk(err_level, &adap->dev, "Not using recovery: %s\n", err_str); + adap->bus_recovery_info = NULL; + + return -EINVAL; diff --git a/queue-5.10/percpu-make-pcpu_nr_empty_pop_pages-per-chunk-type.patch b/queue-5.10/percpu-make-pcpu_nr_empty_pop_pages-per-chunk-type.patch new file mode 100644 index 00000000000..06403f45cc6 --- /dev/null +++ b/queue-5.10/percpu-make-pcpu_nr_empty_pop_pages-per-chunk-type.patch @@ -0,0 +1,133 @@ +From 0760fa3d8f7fceeea508b98899f1c826e10ffe78 Mon Sep 17 00:00:00 2001 +From: Roman Gushchin +Date: Wed, 7 Apr 2021 20:57:33 -0700 +Subject: percpu: make pcpu_nr_empty_pop_pages per chunk type + +From: Roman Gushchin + +commit 0760fa3d8f7fceeea508b98899f1c826e10ffe78 upstream. + +nr_empty_pop_pages is used to guarantee that there are some free +populated pages to satisfy atomic allocations. Accounted and +non-accounted allocations are using separate sets of chunks, +so both need to have a surplus of empty pages. + +This commit makes pcpu_nr_empty_pop_pages and the corresponding logic +per chunk type. + +[Dennis] +This issue came up as I was reviewing [1] and realized I missed this. +Simultaneously, it was reported btrfs was seeing failed atomic +allocations in fsstress tests [2] and [3]. + +[1] https://lore.kernel.org/linux-mm/20210324190626.564297-1-guro@fb.com/ +[2] https://lore.kernel.org/linux-mm/20210401185158.3275.409509F4@e16-tech.com/ +[3] https://lore.kernel.org/linux-mm/CAL3q7H5RNBjCi708GH7jnczAOe0BLnacT9C+OBgA-Dx9jhB6SQ@mail.gmail.com/ + +Fixes: 3c7be18ac9a0 ("mm: memcg/percpu: account percpu memory to memory cgroups") +Cc: stable@vger.kernel.org # 5.9+ +Signed-off-by: Roman Gushchin +Tested-by: Filipe Manana +Signed-off-by: Dennis Zhou +Signed-off-by: Greg Kroah-Hartman +--- + mm/percpu-internal.h | 2 +- + mm/percpu-stats.c | 9 +++++++-- + mm/percpu.c | 14 +++++++------- + 3 files changed, 15 insertions(+), 10 deletions(-) + +--- a/mm/percpu-internal.h ++++ b/mm/percpu-internal.h +@@ -87,7 +87,7 @@ extern spinlock_t pcpu_lock; + + extern struct list_head *pcpu_chunk_lists; + extern int pcpu_nr_slots; +-extern int pcpu_nr_empty_pop_pages; ++extern int pcpu_nr_empty_pop_pages[]; + + extern struct pcpu_chunk *pcpu_first_chunk; + extern struct pcpu_chunk *pcpu_reserved_chunk; +--- a/mm/percpu-stats.c ++++ b/mm/percpu-stats.c +@@ -145,6 +145,7 @@ static int percpu_stats_show(struct seq_ + int slot, max_nr_alloc; + int *buffer; + enum pcpu_chunk_type type; ++ int nr_empty_pop_pages; + + alloc_buffer: + spin_lock_irq(&pcpu_lock); +@@ -165,7 +166,11 @@ alloc_buffer: + goto alloc_buffer; + } + +-#define PL(X) \ ++ nr_empty_pop_pages = 0; ++ for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++) ++ nr_empty_pop_pages += pcpu_nr_empty_pop_pages[type]; ++ ++#define PL(X) \ + seq_printf(m, " %-20s: %12lld\n", #X, (long long int)pcpu_stats_ai.X) + + seq_printf(m, +@@ -196,7 +201,7 @@ alloc_buffer: + PU(nr_max_chunks); + PU(min_alloc_size); + PU(max_alloc_size); +- P("empty_pop_pages", pcpu_nr_empty_pop_pages); ++ P("empty_pop_pages", nr_empty_pop_pages); + seq_putc(m, '\n'); + + #undef PU +--- a/mm/percpu.c ++++ b/mm/percpu.c +@@ -172,10 +172,10 @@ struct list_head *pcpu_chunk_lists __ro_ + static LIST_HEAD(pcpu_map_extend_chunks); + + /* +- * The number of empty populated pages, protected by pcpu_lock. The +- * reserved chunk doesn't contribute to the count. ++ * The number of empty populated pages by chunk type, protected by pcpu_lock. ++ * The reserved chunk doesn't contribute to the count. + */ +-int pcpu_nr_empty_pop_pages; ++int pcpu_nr_empty_pop_pages[PCPU_NR_CHUNK_TYPES]; + + /* + * The number of populated pages in use by the allocator, protected by +@@ -555,7 +555,7 @@ static inline void pcpu_update_empty_pag + { + chunk->nr_empty_pop_pages += nr; + if (chunk != pcpu_reserved_chunk) +- pcpu_nr_empty_pop_pages += nr; ++ pcpu_nr_empty_pop_pages[pcpu_chunk_type(chunk)] += nr; + } + + /* +@@ -1831,7 +1831,7 @@ area_found: + mutex_unlock(&pcpu_alloc_mutex); + } + +- if (pcpu_nr_empty_pop_pages < PCPU_EMPTY_POP_PAGES_LOW) ++ if (pcpu_nr_empty_pop_pages[type] < PCPU_EMPTY_POP_PAGES_LOW) + pcpu_schedule_balance_work(); + + /* clear the areas and return address relative to base address */ +@@ -1999,7 +1999,7 @@ retry_pop: + pcpu_atomic_alloc_failed = false; + } else { + nr_to_pop = clamp(PCPU_EMPTY_POP_PAGES_HIGH - +- pcpu_nr_empty_pop_pages, ++ pcpu_nr_empty_pop_pages[type], + 0, PCPU_EMPTY_POP_PAGES_HIGH); + } + +@@ -2579,7 +2579,7 @@ void __init pcpu_setup_first_chunk(const + + /* link the first chunk in */ + pcpu_first_chunk = chunk; +- pcpu_nr_empty_pop_pages = pcpu_first_chunk->nr_empty_pop_pages; ++ pcpu_nr_empty_pop_pages[PCPU_CHUNK_ROOT] = pcpu_first_chunk->nr_empty_pop_pages; + pcpu_chunk_relocate(pcpu_first_chunk, -1); + + /* include all regions of the first chunk */ diff --git a/queue-5.10/scsi-pm80xx-fix-chip-initialization-failure.patch b/queue-5.10/scsi-pm80xx-fix-chip-initialization-failure.patch new file mode 100644 index 00000000000..53cd702be3a --- /dev/null +++ b/queue-5.10/scsi-pm80xx-fix-chip-initialization-failure.patch @@ -0,0 +1,55 @@ +From 65df7d1986a1909a0869419919e7d9c78d70407e Mon Sep 17 00:00:00 2001 +From: Viswas G +Date: Fri, 2 Apr 2021 11:12:12 +0530 +Subject: scsi: pm80xx: Fix chip initialization failure + +From: Viswas G + +commit 65df7d1986a1909a0869419919e7d9c78d70407e upstream. + +Inbound and outbound queues were not properly configured and that lead to +MPI configuration failure. + +Fixes: 05c6c029a44d ("scsi: pm80xx: Increase number of supported queues") +Cc: stable@vger.kernel.org # 5.10+ +Link: https://lore.kernel.org/r/20210402054212.17834-1-Viswas.G@microchip.com.com +Reported-and-tested-by: Ash Izat +Signed-off-by: Viswas G +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/pm8001/pm8001_hwi.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/pm8001/pm8001_hwi.c ++++ b/drivers/scsi/pm8001/pm8001_hwi.c +@@ -223,7 +223,7 @@ static void init_default_table_values(st + PM8001_EVENT_LOG_SIZE; + pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_option = 0x01; + pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_interrupt = 0x01; +- for (i = 0; i < PM8001_MAX_INB_NUM; i++) { ++ for (i = 0; i < pm8001_ha->max_q_num; i++) { + pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt = + PM8001_MPI_QUEUE | (pm8001_ha->iomb_size << 16) | (0x00<<30); + pm8001_ha->inbnd_q_tbl[i].upper_base_addr = +@@ -249,7 +249,7 @@ static void init_default_table_values(st + pm8001_ha->inbnd_q_tbl[i].producer_idx = 0; + pm8001_ha->inbnd_q_tbl[i].consumer_index = 0; + } +- for (i = 0; i < PM8001_MAX_OUTB_NUM; i++) { ++ for (i = 0; i < pm8001_ha->max_q_num; i++) { + pm8001_ha->outbnd_q_tbl[i].element_size_cnt = + PM8001_MPI_QUEUE | (pm8001_ha->iomb_size << 16) | (0x01<<30); + pm8001_ha->outbnd_q_tbl[i].upper_base_addr = +@@ -671,9 +671,9 @@ static int pm8001_chip_init(struct pm800 + read_outbnd_queue_table(pm8001_ha); + /* update main config table ,inbound table and outbound table */ + update_main_config_table(pm8001_ha); +- for (i = 0; i < PM8001_MAX_INB_NUM; i++) ++ for (i = 0; i < pm8001_ha->max_q_num; i++) + update_inbnd_queue_table(pm8001_ha, i); +- for (i = 0; i < PM8001_MAX_OUTB_NUM; i++) ++ for (i = 0; i < pm8001_ha->max_q_num; i++) + update_outbnd_queue_table(pm8001_ha, i); + /* 8081 controller donot require these operations */ + if (deviceid != 0x8081 && deviceid != 0x0042) { diff --git a/queue-5.10/scsi-target-iscsi-fix-zero-tag-inside-a-trace-event.patch b/queue-5.10/scsi-target-iscsi-fix-zero-tag-inside-a-trace-event.patch new file mode 100644 index 00000000000..d05f55ed70b --- /dev/null +++ b/queue-5.10/scsi-target-iscsi-fix-zero-tag-inside-a-trace-event.patch @@ -0,0 +1,42 @@ +From 0352c3d3959a6cf543075b88c7e662fd3546f12e Mon Sep 17 00:00:00 2001 +From: Roman Bolshakov +Date: Sun, 4 Apr 2021 00:54:15 +0300 +Subject: scsi: target: iscsi: Fix zero tag inside a trace event + +From: Roman Bolshakov + +commit 0352c3d3959a6cf543075b88c7e662fd3546f12e upstream. + +target_sequencer_start event is triggered inside target_cmd_init_cdb(). +se_cmd.tag is not initialized with ITT at the moment so the event always +prints zero tag. + +Link: https://lore.kernel.org/r/20210403215415.95077-1-r.bolshakov@yadro.com +Cc: stable@vger.kernel.org # 5.10+ +Reviewed-by: Mike Christie +Signed-off-by: Roman Bolshakov +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/target/iscsi/iscsi_target.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -1166,6 +1166,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_c + + target_get_sess_cmd(&cmd->se_cmd, true); + ++ cmd->se_cmd.tag = (__force u32)cmd->init_task_tag; + cmd->sense_reason = target_cmd_init_cdb(&cmd->se_cmd, hdr->cdb); + if (cmd->sense_reason) { + if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) { +@@ -1180,8 +1181,6 @@ int iscsit_setup_scsi_cmd(struct iscsi_c + if (cmd->sense_reason) + goto attach_cmd; + +- /* only used for printks or comparing with ->ref_task_tag */ +- cmd->se_cmd.tag = (__force u32)cmd->init_task_tag; + cmd->sense_reason = target_cmd_parse_cdb(&cmd->se_cmd); + if (cmd->sense_reason) + goto attach_cmd; diff --git a/queue-5.10/series b/queue-5.10/series index aedf0b93229..2b19dc8f826 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -68,3 +68,14 @@ mac80211-fix-txq-ac-confusion.patch net-hsr-reset-mac-header-for-tx-path.patch net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch net-let-skb_orphan_partial-wake-up-waiters.patch +thunderbolt-fix-a-leak-in-tb_retimer_add.patch +thunderbolt-fix-off-by-one-in-tb_port_find_retimer.patch +usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch +usbip-stub-dev-synchronize-sysfs-code-paths.patch +usbip-vudc-synchronize-sysfs-code-paths.patch +usbip-synchronize-event-handler-with-sysfs-code-paths.patch +driver-core-fix-locking-bug-in-deferred_probe_timeout_work_func.patch +scsi-pm80xx-fix-chip-initialization-failure.patch +scsi-target-iscsi-fix-zero-tag-inside-a-trace-event.patch +percpu-make-pcpu_nr_empty_pop_pages-per-chunk-type.patch +i2c-turn-recovery-error-on-init-to-debug.patch diff --git a/queue-5.10/thunderbolt-fix-a-leak-in-tb_retimer_add.patch b/queue-5.10/thunderbolt-fix-a-leak-in-tb_retimer_add.patch new file mode 100644 index 00000000000..b48d9398cc0 --- /dev/null +++ b/queue-5.10/thunderbolt-fix-a-leak-in-tb_retimer_add.patch @@ -0,0 +1,35 @@ +From bec4d7c93afc07dd0454ae41c559513f858cfb83 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 29 Mar 2021 09:07:18 +0300 +Subject: thunderbolt: Fix a leak in tb_retimer_add() + +From: Dan Carpenter + +commit bec4d7c93afc07dd0454ae41c559513f858cfb83 upstream. + +After the device_register() succeeds, then the correct way to clean up +is to call device_unregister(). The unregister calls both device_del() +and device_put(). Since this code was only device_del() it results in +a memory leak. + +Fixes: dacb12877d92 ("thunderbolt: Add support for on-board retimers") +Cc: stable@vger.kernel.org +Signed-off-by: Dan Carpenter +Reviewed-by: Jason Gunthorpe +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/retimer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/thunderbolt/retimer.c ++++ b/drivers/thunderbolt/retimer.c +@@ -347,7 +347,7 @@ static int tb_retimer_add(struct tb_port + ret = tb_retimer_nvm_add(rt); + if (ret) { + dev_err(&rt->dev, "failed to add NVM devices: %d\n", ret); +- device_del(&rt->dev); ++ device_unregister(&rt->dev); + return ret; + } + diff --git a/queue-5.10/thunderbolt-fix-off-by-one-in-tb_port_find_retimer.patch b/queue-5.10/thunderbolt-fix-off-by-one-in-tb_port_find_retimer.patch new file mode 100644 index 00000000000..bdb4d68ff3b --- /dev/null +++ b/queue-5.10/thunderbolt-fix-off-by-one-in-tb_port_find_retimer.patch @@ -0,0 +1,32 @@ +From 08fe7ae1857080f5075df5ac7fef2ecd4e289117 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 29 Mar 2021 09:08:01 +0300 +Subject: thunderbolt: Fix off by one in tb_port_find_retimer() + +From: Dan Carpenter + +commit 08fe7ae1857080f5075df5ac7fef2ecd4e289117 upstream. + +This array uses 1-based indexing so it corrupts memory one element +beyond of the array. Fix it by making the array one element larger. + +Fixes: dacb12877d92 ("thunderbolt: Add support for on-board retimers") +Cc: stable@vger.kernel.org +Signed-off-by: Dan Carpenter +Signed-off-by: Mika Westerberg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thunderbolt/retimer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/thunderbolt/retimer.c ++++ b/drivers/thunderbolt/retimer.c +@@ -406,7 +406,7 @@ static struct tb_retimer *tb_port_find_r + */ + int tb_retimer_scan(struct tb_port *port) + { +- u32 status[TB_MAX_RETIMER_INDEX] = {}; ++ u32 status[TB_MAX_RETIMER_INDEX + 1] = {}; + int ret, i, last_idx = 0; + + if (!port->cap_usb4) diff --git a/queue-5.10/usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch b/queue-5.10/usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch new file mode 100644 index 00000000000..d27b7a09033 --- /dev/null +++ b/queue-5.10/usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch @@ -0,0 +1,149 @@ +From 4e9c93af7279b059faf5bb1897ee90512b258a12 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Mon, 29 Mar 2021 19:36:48 -0600 +Subject: usbip: add sysfs_lock to synchronize sysfs code paths + +From: Shuah Khan + +commit 4e9c93af7279b059faf5bb1897ee90512b258a12 upstream. + +Fuzzing uncovered race condition between sysfs code paths in usbip +drivers. Device connect/disconnect code paths initiated through +sysfs interface are prone to races if disconnect happens during +connect and vice versa. + +This problem is common to all drivers while it can be reproduced easily +in vhci_hcd. Add a sysfs_lock to usbip_device struct to protect the paths. + +Use this in vhci_hcd to protect sysfs paths. For a complete fix, usip_host +and usip-vudc drivers and the event handler will have to use this lock to +protect the paths. These changes will be done in subsequent patches. + +Cc: stable@vger.kernel.org +Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com +Signed-off-by: Shuah Khan +Link: https://lore.kernel.org/r/b6568f7beae702bbc236a545d3c020106ca75eac.1616807117.git.skhan@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/usbip/usbip_common.h | 3 +++ + drivers/usb/usbip/vhci_hcd.c | 1 + + drivers/usb/usbip/vhci_sysfs.c | 30 +++++++++++++++++++++++++----- + 3 files changed, 29 insertions(+), 5 deletions(-) + +--- a/drivers/usb/usbip/usbip_common.h ++++ b/drivers/usb/usbip/usbip_common.h +@@ -263,6 +263,9 @@ struct usbip_device { + /* lock for status */ + spinlock_t lock; + ++ /* mutex for synchronizing sysfs store paths */ ++ struct mutex sysfs_lock; ++ + int sockfd; + struct socket *tcp_socket; + +--- a/drivers/usb/usbip/vhci_hcd.c ++++ b/drivers/usb/usbip/vhci_hcd.c +@@ -1101,6 +1101,7 @@ static void vhci_device_init(struct vhci + vdev->ud.side = USBIP_VHCI; + vdev->ud.status = VDEV_ST_NULL; + spin_lock_init(&vdev->ud.lock); ++ mutex_init(&vdev->ud.sysfs_lock); + + INIT_LIST_HEAD(&vdev->priv_rx); + INIT_LIST_HEAD(&vdev->priv_tx); +--- a/drivers/usb/usbip/vhci_sysfs.c ++++ b/drivers/usb/usbip/vhci_sysfs.c +@@ -185,6 +185,8 @@ static int vhci_port_disconnect(struct v + + usbip_dbg_vhci_sysfs("enter\n"); + ++ mutex_lock(&vdev->ud.sysfs_lock); ++ + /* lock */ + spin_lock_irqsave(&vhci->lock, flags); + spin_lock(&vdev->ud.lock); +@@ -195,6 +197,7 @@ static int vhci_port_disconnect(struct v + /* unlock */ + spin_unlock(&vdev->ud.lock); + spin_unlock_irqrestore(&vhci->lock, flags); ++ mutex_unlock(&vdev->ud.sysfs_lock); + + return -EINVAL; + } +@@ -205,6 +208,8 @@ static int vhci_port_disconnect(struct v + + usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); + ++ mutex_unlock(&vdev->ud.sysfs_lock); ++ + return 0; + } + +@@ -349,30 +354,36 @@ static ssize_t attach_store(struct devic + else + vdev = &vhci->vhci_hcd_hs->vdev[rhport]; + ++ mutex_lock(&vdev->ud.sysfs_lock); ++ + /* Extract socket from fd. */ + socket = sockfd_lookup(sockfd, &err); + if (!socket) { + dev_err(dev, "failed to lookup sock"); +- return -EINVAL; ++ err = -EINVAL; ++ goto unlock_mutex; + } + if (socket->type != SOCK_STREAM) { + dev_err(dev, "Expecting SOCK_STREAM - found %d", + socket->type); + sockfd_put(socket); +- return -EINVAL; ++ err = -EINVAL; ++ goto unlock_mutex; + } + + /* create threads before locking */ + tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx"); + if (IS_ERR(tcp_rx)) { + sockfd_put(socket); +- return -EINVAL; ++ err = -EINVAL; ++ goto unlock_mutex; + } + tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx"); + if (IS_ERR(tcp_tx)) { + kthread_stop(tcp_rx); + sockfd_put(socket); +- return -EINVAL; ++ err = -EINVAL; ++ goto unlock_mutex; + } + + /* get task structs now */ +@@ -397,7 +408,8 @@ static ssize_t attach_store(struct devic + * Will be retried from userspace + * if there's another free port. + */ +- return -EBUSY; ++ err = -EBUSY; ++ goto unlock_mutex; + } + + dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n", +@@ -422,7 +434,15 @@ static ssize_t attach_store(struct devic + + rh_port_connect(vdev, speed); + ++ dev_info(dev, "Device attached\n"); ++ ++ mutex_unlock(&vdev->ud.sysfs_lock); ++ + return count; ++ ++unlock_mutex: ++ mutex_unlock(&vdev->ud.sysfs_lock); ++ return err; + } + static DEVICE_ATTR_WO(attach); + diff --git a/queue-5.10/usbip-stub-dev-synchronize-sysfs-code-paths.patch b/queue-5.10/usbip-stub-dev-synchronize-sysfs-code-paths.patch new file mode 100644 index 00000000000..bfe8f6b52fe --- /dev/null +++ b/queue-5.10/usbip-stub-dev-synchronize-sysfs-code-paths.patch @@ -0,0 +1,85 @@ +From 9dbf34a834563dada91366c2ac266f32ff34641a Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Mon, 29 Mar 2021 19:36:49 -0600 +Subject: usbip: stub-dev synchronize sysfs code paths + +From: Shuah Khan + +commit 9dbf34a834563dada91366c2ac266f32ff34641a upstream. + +Fuzzing uncovered race condition between sysfs code paths in usbip +drivers. Device connect/disconnect code paths initiated through +sysfs interface are prone to races if disconnect happens during +connect and vice versa. + +Use sysfs_lock to protect sysfs paths in stub-dev. + +Cc: stable@vger.kernel.org +Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com +Signed-off-by: Shuah Khan +Link: https://lore.kernel.org/r/2b182f3561b4a065bf3bf6dce3b0e9944ba17b3f.1616807117.git.skhan@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/usbip/stub_dev.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/usb/usbip/stub_dev.c ++++ b/drivers/usb/usbip/stub_dev.c +@@ -63,6 +63,7 @@ static ssize_t usbip_sockfd_store(struct + + dev_info(dev, "stub up\n"); + ++ mutex_lock(&sdev->ud.sysfs_lock); + spin_lock_irq(&sdev->ud.lock); + + if (sdev->ud.status != SDEV_ST_AVAILABLE) { +@@ -87,13 +88,13 @@ static ssize_t usbip_sockfd_store(struct + tcp_rx = kthread_create(stub_rx_loop, &sdev->ud, "stub_rx"); + if (IS_ERR(tcp_rx)) { + sockfd_put(socket); +- return -EINVAL; ++ goto unlock_mutex; + } + tcp_tx = kthread_create(stub_tx_loop, &sdev->ud, "stub_tx"); + if (IS_ERR(tcp_tx)) { + kthread_stop(tcp_rx); + sockfd_put(socket); +- return -EINVAL; ++ goto unlock_mutex; + } + + /* get task structs now */ +@@ -112,6 +113,8 @@ static ssize_t usbip_sockfd_store(struct + wake_up_process(sdev->ud.tcp_rx); + wake_up_process(sdev->ud.tcp_tx); + ++ mutex_unlock(&sdev->ud.sysfs_lock); ++ + } else { + dev_info(dev, "stub down\n"); + +@@ -122,6 +125,7 @@ static ssize_t usbip_sockfd_store(struct + spin_unlock_irq(&sdev->ud.lock); + + usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN); ++ mutex_unlock(&sdev->ud.sysfs_lock); + } + + return count; +@@ -130,6 +134,8 @@ sock_err: + sockfd_put(socket); + err: + spin_unlock_irq(&sdev->ud.lock); ++unlock_mutex: ++ mutex_unlock(&sdev->ud.sysfs_lock); + return -EINVAL; + } + static DEVICE_ATTR_WO(usbip_sockfd); +@@ -270,6 +276,7 @@ static struct stub_device *stub_device_a + sdev->ud.side = USBIP_STUB; + sdev->ud.status = SDEV_ST_AVAILABLE; + spin_lock_init(&sdev->ud.lock); ++ mutex_init(&sdev->ud.sysfs_lock); + sdev->ud.tcp_socket = NULL; + sdev->ud.sockfd = -1; + diff --git a/queue-5.10/usbip-synchronize-event-handler-with-sysfs-code-paths.patch b/queue-5.10/usbip-synchronize-event-handler-with-sysfs-code-paths.patch new file mode 100644 index 00000000000..5f0818ccb9f --- /dev/null +++ b/queue-5.10/usbip-synchronize-event-handler-with-sysfs-code-paths.patch @@ -0,0 +1,44 @@ +From 363eaa3a450abb4e63bd6e3ad79d1f7a0f717814 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Mon, 29 Mar 2021 19:36:51 -0600 +Subject: usbip: synchronize event handler with sysfs code paths + +From: Shuah Khan + +commit 363eaa3a450abb4e63bd6e3ad79d1f7a0f717814 upstream. + +Fuzzing uncovered race condition between sysfs code paths in usbip +drivers. Device connect/disconnect code paths initiated through +sysfs interface are prone to races if disconnect happens during +connect and vice versa. + +Use sysfs_lock to synchronize event handler with sysfs paths +in usbip drivers. + +Cc: stable@vger.kernel.org +Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com +Signed-off-by: Shuah Khan +Link: https://lore.kernel.org/r/c5c8723d3f29dfe3d759cfaafa7dd16b0dfe2918.1616807117.git.skhan@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/usbip/usbip_event.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/usbip/usbip_event.c ++++ b/drivers/usb/usbip/usbip_event.c +@@ -70,6 +70,7 @@ static void event_handler(struct work_st + while ((ud = get_event()) != NULL) { + usbip_dbg_eh("pending event %lx\n", ud->event); + ++ mutex_lock(&ud->sysfs_lock); + /* + * NOTE: shutdown must come first. + * Shutdown the device. +@@ -90,6 +91,7 @@ static void event_handler(struct work_st + ud->eh_ops.unusable(ud); + unset_event(ud, USBIP_EH_UNUSABLE); + } ++ mutex_unlock(&ud->sysfs_lock); + + wake_up(&ud->eh_waitq); + } diff --git a/queue-5.10/usbip-vudc-synchronize-sysfs-code-paths.patch b/queue-5.10/usbip-vudc-synchronize-sysfs-code-paths.patch new file mode 100644 index 00000000000..fa70cd290c0 --- /dev/null +++ b/queue-5.10/usbip-vudc-synchronize-sysfs-code-paths.patch @@ -0,0 +1,71 @@ +From bd8b82042269a95db48074b8bb400678dbac1815 Mon Sep 17 00:00:00 2001 +From: Shuah Khan +Date: Mon, 29 Mar 2021 19:36:50 -0600 +Subject: usbip: vudc synchronize sysfs code paths + +From: Shuah Khan + +commit bd8b82042269a95db48074b8bb400678dbac1815 upstream. + +Fuzzing uncovered race condition between sysfs code paths in usbip +drivers. Device connect/disconnect code paths initiated through +sysfs interface are prone to races if disconnect happens during +connect and vice versa. + +Use sysfs_lock to protect sysfs paths in vudc. + +Cc: stable@vger.kernel.org +Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com +Signed-off-by: Shuah Khan +Link: https://lore.kernel.org/r/caabcf3fc87bdae970509b5ff32d05bb7ce2fb15.1616807117.git.skhan@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/usbip/vudc_dev.c | 1 + + drivers/usb/usbip/vudc_sysfs.c | 5 +++++ + 2 files changed, 6 insertions(+) + +--- a/drivers/usb/usbip/vudc_dev.c ++++ b/drivers/usb/usbip/vudc_dev.c +@@ -572,6 +572,7 @@ static int init_vudc_hw(struct vudc *udc + init_waitqueue_head(&udc->tx_waitq); + + spin_lock_init(&ud->lock); ++ mutex_init(&ud->sysfs_lock); + ud->status = SDEV_ST_AVAILABLE; + ud->side = USBIP_VUDC; + +--- a/drivers/usb/usbip/vudc_sysfs.c ++++ b/drivers/usb/usbip/vudc_sysfs.c +@@ -112,6 +112,7 @@ static ssize_t usbip_sockfd_store(struct + dev_err(dev, "no device"); + return -ENODEV; + } ++ mutex_lock(&udc->ud.sysfs_lock); + spin_lock_irqsave(&udc->lock, flags); + /* Don't export what we don't have */ + if (!udc->driver || !udc->pullup) { +@@ -187,6 +188,8 @@ static ssize_t usbip_sockfd_store(struct + + wake_up_process(udc->ud.tcp_rx); + wake_up_process(udc->ud.tcp_tx); ++ ++ mutex_unlock(&udc->ud.sysfs_lock); + return count; + + } else { +@@ -207,6 +210,7 @@ static ssize_t usbip_sockfd_store(struct + } + + spin_unlock_irqrestore(&udc->lock, flags); ++ mutex_unlock(&udc->ud.sysfs_lock); + + return count; + +@@ -216,6 +220,7 @@ unlock_ud: + spin_unlock_irq(&udc->ud.lock); + unlock: + spin_unlock_irqrestore(&udc->lock, flags); ++ mutex_unlock(&udc->ud.sysfs_lock); + + return ret; + }