From 7476d354bd756a0b9489362976bbfefc73a04dff Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 10 May 2021 10:28:27 +0200 Subject: [PATCH] 5.4-stable patches added patches: ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch ext4-fix-error-code-in-ext4_commit_super.patch kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch media-dvb-usb-fix-use-after-free-access.patch media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch media-staging-intel-ipu3-fix-set_fmt-error-handling.patch rsi-use-resume_noirq-for-sdio.patch tty-fix-memory-leak-in-vc_deallocate.patch usb-dwc2-fix-session-request-interrupt-handler.patch usb-dwc3-gadget-fix-start_transfer-link-state-check.patch usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch usb-gadget-fix-double-free-of-device-descriptor-pointers.patch usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch --- ...set-sb_active-in-ext4_orphan_cleanup.patch | 49 +++++++ ...tive-report-of-incorrect-used-inodes.patch | 96 ++++++++++++++ ...-fix-error-code-in-ext4_commit_super.patch | 38 ++++++ ...en-the-content-of-.config-is-changed.patch | 88 +++++++++++++ ...leak-at-error-in-dvb_usb_device_init.patch | 120 ++++++++++++++++++ ...ia-dvb-usb-fix-use-after-free-access.patch | 76 +++++++++++ ...memory-leak-in-dvb_media_device_free.patch | 37 ++++++ ...ntel-ipu3-fix-memory-leak-in-imu_fmt.patch | 49 +++++++ ...u3-fix-race-condition-during-set_fmt.patch | 105 +++++++++++++++ ...ntel-ipu3-fix-set_fmt-error-handling.patch | 57 +++++++++ queue-5.4/rsi-use-resume_noirq-for-sdio.patch | 46 +++++++ queue-5.4/series | 18 ++- ...include-it-in-requested-capabilities.patch | 47 ------- ...tty-fix-memory-leak-in-vc_deallocate.patch | 34 +++++ ...ix-session-request-interrupt-handler.patch | 47 +++++++ ...-fix-start_transfer-link-state-check.patch | 63 +++++++++ ...et-dummy_hcd-fix-gpf-in-gadget_setup.patch | 90 +++++++++++++ ...e-free-of-device-descriptor-pointers.patch | 44 +++++++ ...ing-table-fix-for-multiple-languages.patch | 44 +++++++ 19 files changed, 1100 insertions(+), 48 deletions(-) create mode 100644 queue-5.4/ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch create mode 100644 queue-5.4/ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch create mode 100644 queue-5.4/ext4-fix-error-code-in-ext4_commit_super.patch create mode 100644 queue-5.4/kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch create mode 100644 queue-5.4/media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch create mode 100644 queue-5.4/media-dvb-usb-fix-use-after-free-access.patch create mode 100644 queue-5.4/media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch create mode 100644 queue-5.4/media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch create mode 100644 queue-5.4/media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch create mode 100644 queue-5.4/media-staging-intel-ipu3-fix-set_fmt-error-handling.patch create mode 100644 queue-5.4/rsi-use-resume_noirq-for-sdio.patch delete mode 100644 queue-5.4/smb3-when-mounting-with-multichannel-include-it-in-requested-capabilities.patch create mode 100644 queue-5.4/tty-fix-memory-leak-in-vc_deallocate.patch create mode 100644 queue-5.4/usb-dwc2-fix-session-request-interrupt-handler.patch create mode 100644 queue-5.4/usb-dwc3-gadget-fix-start_transfer-link-state-check.patch create mode 100644 queue-5.4/usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch create mode 100644 queue-5.4/usb-gadget-fix-double-free-of-device-descriptor-pointers.patch create mode 100644 queue-5.4/usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch diff --git a/queue-5.4/ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch b/queue-5.4/ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch new file mode 100644 index 00000000000..1d1505e48c8 --- /dev/null +++ b/queue-5.4/ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch @@ -0,0 +1,49 @@ +From 72ffb49a7b623c92a37657eda7cc46a06d3e8398 Mon Sep 17 00:00:00 2001 +From: Zhang Yi +Date: Wed, 31 Mar 2021 11:31:38 +0800 +Subject: ext4: do not set SB_ACTIVE in ext4_orphan_cleanup() + +From: Zhang Yi + +commit 72ffb49a7b623c92a37657eda7cc46a06d3e8398 upstream. + +When CONFIG_QUOTA is enabled, if we failed to mount the filesystem due +to some error happens behind ext4_orphan_cleanup(), it will end up +triggering a after free issue of super_block. The problem is that +ext4_orphan_cleanup() will set SB_ACTIVE flag if CONFIG_QUOTA is +enabled, after we cleanup the truncated inodes, the last iput() will put +them into the lru list, and these inodes' pages may probably dirty and +will be write back by the writeback thread, so it could be raced by +freeing super_block in the error path of mount_bdev(). + +After check the setting of SB_ACTIVE flag in ext4_orphan_cleanup(), it +was used to ensure updating the quota file properly, but evict inode and +trash data immediately in the last iput does not affect the quotafile, +so setting the SB_ACTIVE flag seems not required[1]. Fix this issue by +just remove the SB_ACTIVE setting. + +[1] https://lore.kernel.org/linux-ext4/99cce8ca-e4a0-7301-840f-2ace67c551f3@huawei.com/T/#m04990cfbc4f44592421736b504afcc346b2a7c00 + +Cc: stable@kernel.org +Signed-off-by: Zhang Yi +Tested-by: Jan Kara +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20210331033138.918975-1-yi.zhang@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/super.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2675,9 +2675,6 @@ static void ext4_orphan_cleanup(struct s + sb->s_flags &= ~SB_RDONLY; + } + #ifdef CONFIG_QUOTA +- /* Needed for iput() to work correctly and not trash data */ +- sb->s_flags |= SB_ACTIVE; +- + /* + * Turn on quotas which were not enabled for read-only mounts if + * filesystem has quota feature, so that they are updated correctly. diff --git a/queue-5.4/ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch b/queue-5.4/ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch new file mode 100644 index 00000000000..55603048b63 --- /dev/null +++ b/queue-5.4/ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch @@ -0,0 +1,96 @@ +From a149d2a5cabbf6507a7832a1c4fd2593c55fd450 Mon Sep 17 00:00:00 2001 +From: Zhang Yi +Date: Wed, 31 Mar 2021 20:15:16 +0800 +Subject: ext4: fix check to prevent false positive report of incorrect used inodes + +From: Zhang Yi + +commit a149d2a5cabbf6507a7832a1c4fd2593c55fd450 upstream. + +Commit <50122847007> ("ext4: fix check to prevent initializing reserved +inodes") check the block group zero and prevent initializing reserved +inodes. But in some special cases, the reserved inode may not all belong +to the group zero, it may exist into the second group if we format +filesystem below. + + mkfs.ext4 -b 4096 -g 8192 -N 1024 -I 4096 /dev/sda + +So, it will end up triggering a false positive report of a corrupted +file system. This patch fix it by avoid check reserved inodes if no free +inode blocks will be zeroed. + +Cc: stable@kernel.org +Fixes: 50122847007 ("ext4: fix check to prevent initializing reserved inodes") +Signed-off-by: Zhang Yi +Suggested-by: Jan Kara +Link: https://lore.kernel.org/r/20210331121516.2243099-1-yi.zhang@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/ialloc.c | 48 ++++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 16 deletions(-) + +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -1353,6 +1353,7 @@ int ext4_init_inode_table(struct super_b + handle_t *handle; + ext4_fsblk_t blk; + int num, ret = 0, used_blks = 0; ++ unsigned long used_inos = 0; + + /* This should not happen, but just to be sure check this */ + if (sb_rdonly(sb)) { +@@ -1383,22 +1384,37 @@ int ext4_init_inode_table(struct super_b + * used inodes so we need to skip blocks with used inodes in + * inode table. + */ +- if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) +- used_blks = DIV_ROUND_UP((EXT4_INODES_PER_GROUP(sb) - +- ext4_itable_unused_count(sb, gdp)), +- sbi->s_inodes_per_block); +- +- if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group) || +- ((group == 0) && ((EXT4_INODES_PER_GROUP(sb) - +- ext4_itable_unused_count(sb, gdp)) < +- EXT4_FIRST_INO(sb)))) { +- ext4_error(sb, "Something is wrong with group %u: " +- "used itable blocks: %d; " +- "itable unused count: %u", +- group, used_blks, +- ext4_itable_unused_count(sb, gdp)); +- ret = 1; +- goto err_out; ++ if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) { ++ used_inos = EXT4_INODES_PER_GROUP(sb) - ++ ext4_itable_unused_count(sb, gdp); ++ used_blks = DIV_ROUND_UP(used_inos, sbi->s_inodes_per_block); ++ ++ /* Bogus inode unused count? */ ++ if (used_blks < 0 || used_blks > sbi->s_itb_per_group) { ++ ext4_error(sb, "Something is wrong with group %u: " ++ "used itable blocks: %d; " ++ "itable unused count: %u", ++ group, used_blks, ++ ext4_itable_unused_count(sb, gdp)); ++ ret = 1; ++ goto err_out; ++ } ++ ++ used_inos += group * EXT4_INODES_PER_GROUP(sb); ++ /* ++ * Are there some uninitialized inodes in the inode table ++ * before the first normal inode? ++ */ ++ if ((used_blks != sbi->s_itb_per_group) && ++ (used_inos < EXT4_FIRST_INO(sb))) { ++ ext4_error(sb, "Something is wrong with group %u: " ++ "itable unused count: %u; " ++ "itables initialized count: %ld", ++ group, ext4_itable_unused_count(sb, gdp), ++ used_inos); ++ ret = 1; ++ goto err_out; ++ } + } + + blk = ext4_inode_table(sb, gdp) + used_blks; diff --git a/queue-5.4/ext4-fix-error-code-in-ext4_commit_super.patch b/queue-5.4/ext4-fix-error-code-in-ext4_commit_super.patch new file mode 100644 index 00000000000..9e04e45866d --- /dev/null +++ b/queue-5.4/ext4-fix-error-code-in-ext4_commit_super.patch @@ -0,0 +1,38 @@ +From f88f1466e2a2e5ca17dfada436d3efa1b03a3972 Mon Sep 17 00:00:00 2001 +From: Fengnan Chang +Date: Fri, 2 Apr 2021 18:16:31 +0800 +Subject: ext4: fix error code in ext4_commit_super + +From: Fengnan Chang + +commit f88f1466e2a2e5ca17dfada436d3efa1b03a3972 upstream. + +We should set the error code when ext4_commit_super check argument failed. +Found in code review. +Fixes: c4be0c1dc4cdc ("filesystem freeze: add error handling of write_super_lockfs/unlockfs"). + +Cc: stable@kernel.org +Signed-off-by: Fengnan Chang +Reviewed-by: Andreas Dilger +Link: https://lore.kernel.org/r/20210402101631.561-1-changfengnan@vivo.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/super.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -5057,8 +5057,10 @@ static int ext4_commit_super(struct supe + struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; + int error = 0; + +- if (!sbh || block_device_ejected(sb)) +- return error; ++ if (!sbh) ++ return -EINVAL; ++ if (block_device_ejected(sb)) ++ return -ENODEV; + + /* + * If the file system is mounted read-only, don't update the diff --git a/queue-5.4/kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch b/queue-5.4/kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch new file mode 100644 index 00000000000..dce4a371bb2 --- /dev/null +++ b/queue-5.4/kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch @@ -0,0 +1,88 @@ +From 46b41d5dd8019b264717978c39c43313a524d033 Mon Sep 17 00:00:00 2001 +From: Masahiro Yamada +Date: Sun, 25 Apr 2021 15:24:07 +0900 +Subject: kbuild: update config_data.gz only when the content of .config is changed + +From: Masahiro Yamada + +commit 46b41d5dd8019b264717978c39c43313a524d033 upstream. + +If the timestamp of the .config file is updated, config_data.gz is +regenerated, then vmlinux is re-linked. This occurs even if the content +of the .config has not changed at all. + +This issue was mitigated by commit 67424f61f813 ("kconfig: do not write +.config if the content is the same"); Kconfig does not update the +.config when it ends up with the identical configuration. + +The issue is remaining when the .config is created by *_defconfig with +some config fragment(s) applied on top. + +This is typical for powerpc and mips, where several *_defconfig targets +are constructed by using merge_config.sh. + +One workaround is to have the copy of the .config. The filechk rule +updates the copy, kernel/config_data, by checking the content instead +of the timestamp. + +With this commit, the second run with the same configuration avoids +the needless rebuilds. + + $ make ARCH=mips defconfig all + [ snip ] + $ make ARCH=mips defconfig all + *** Default configuration is based on target '32r2el_defconfig' + Using ./arch/mips/configs/generic_defconfig as base + Merging arch/mips/configs/generic/32r2.config + Merging arch/mips/configs/generic/el.config + Merging ./arch/mips/configs/generic/board-boston.config + Merging ./arch/mips/configs/generic/board-ni169445.config + Merging ./arch/mips/configs/generic/board-ocelot.config + Merging ./arch/mips/configs/generic/board-ranchu.config + Merging ./arch/mips/configs/generic/board-sead-3.config + Merging ./arch/mips/configs/generic/board-xilfpga.config + # + # configuration written to .config + # + SYNC include/config/auto.conf + CALL scripts/checksyscalls.sh + CALL scripts/atomic/check-atomics.sh + CHK include/generated/compile.h + CHK include/generated/autoksyms.h + +Reported-by: Elliot Berman +Signed-off-by: Masahiro Yamada +Signed-off-by: Greg Kroah-Hartman +--- + kernel/.gitignore | 1 + + kernel/Makefile | 9 +++++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +--- a/kernel/.gitignore ++++ b/kernel/.gitignore +@@ -1,4 +1,5 @@ + # ++/config_data + # Generated files + # + kheaders.md5 +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -122,10 +122,15 @@ KCOV_INSTRUMENT_stackleak.o := n + + $(obj)/configs.o: $(obj)/config_data.gz + +-targets += config_data.gz +-$(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE ++targets += config_data config_data.gz ++$(obj)/config_data.gz: $(obj)/config_data FORCE + $(call if_changed,gzip) + ++filechk_cat = cat $< ++ ++$(obj)/config_data: $(KCONFIG_CONFIG) FORCE ++ $(call filechk,cat) ++ + $(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz + + quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz diff --git a/queue-5.4/media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch b/queue-5.4/media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch new file mode 100644 index 00000000000..8c6ee88e244 --- /dev/null +++ b/queue-5.4/media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch @@ -0,0 +1,120 @@ +From 13a79f14ab285120bc4977e00a7c731e8143f548 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 1 Feb 2021 09:32:46 +0100 +Subject: media: dvb-usb: Fix memory leak at error in dvb_usb_device_init() + +From: Takashi Iwai + +commit 13a79f14ab285120bc4977e00a7c731e8143f548 upstream. + +dvb_usb_device_init() allocates a dvb_usb_device object, but it +doesn't release the object by itself even at errors. The object is +released in the callee side (dvb_usb_init()) in some error cases via +dvb_usb_exit() call, but it also missed the object free in other error +paths. And, the caller (it's only dvb_usb_device_init()) doesn't seem +caring the resource management as well, hence those memories are +leaked. + +This patch assures releasing the memory at the error path in +dvb_usb_device_init(). Now dvb_usb_init() frees the resources it +allocated but leaves the passed dvb_usb_device object intact. In +turn, the dvb_usb_device object is released in dvb_usb_device_init() +instead. +We could use dvb_usb_exit() function for releasing everything in the +callee (as it was used for some error cases in the original code), but +releasing the passed object in the callee is non-intuitive and +error-prone. So I took this approach (which is more standard in Linus +kernel code) although it ended with a bit more open codes. + +Along with the change, the patch makes sure that USB intfdata is reset +and don't return the bogus pointer to the caller of +dvb_usb_device_init() at the error path, too. + +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/dvb-usb/dvb-usb-init.c | 47 ++++++++++++++++++++----------- + 1 file changed, 31 insertions(+), 16 deletions(-) + +--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c ++++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c +@@ -170,22 +170,20 @@ static int dvb_usb_init(struct dvb_usb_d + + if (d->props.priv_init != NULL) { + ret = d->props.priv_init(d); +- if (ret != 0) { +- kfree(d->priv); +- d->priv = NULL; +- return ret; +- } ++ if (ret != 0) ++ goto err_priv_init; + } + } + + /* check the capabilities and set appropriate variables */ + dvb_usb_device_power_ctrl(d, 1); + +- if ((ret = dvb_usb_i2c_init(d)) || +- (ret = dvb_usb_adapter_init(d, adapter_nums))) { +- dvb_usb_exit(d); +- return ret; +- } ++ ret = dvb_usb_i2c_init(d); ++ if (ret) ++ goto err_i2c_init; ++ ret = dvb_usb_adapter_init(d, adapter_nums); ++ if (ret) ++ goto err_adapter_init; + + if ((ret = dvb_usb_remote_init(d))) + err("could not initialize remote control."); +@@ -193,6 +191,17 @@ static int dvb_usb_init(struct dvb_usb_d + dvb_usb_device_power_ctrl(d, 0); + + return 0; ++ ++err_adapter_init: ++ dvb_usb_adapter_exit(d); ++err_i2c_init: ++ dvb_usb_i2c_exit(d); ++ if (d->priv && d->props.priv_destroy) ++ d->props.priv_destroy(d); ++err_priv_init: ++ kfree(d->priv); ++ d->priv = NULL; ++ return ret; + } + + /* determine the name and the state of the just found USB device */ +@@ -296,15 +305,21 @@ int dvb_usb_device_init(struct usb_inter + + usb_set_intfdata(intf, d); + +- if (du != NULL) ++ ret = dvb_usb_init(d, adapter_nums); ++ if (ret) { ++ info("%s error while loading driver (%d)", desc->name, ret); ++ goto error; ++ } ++ ++ if (du) + *du = d; + +- ret = dvb_usb_init(d, adapter_nums); ++ info("%s successfully initialized and connected.", desc->name); ++ return 0; + +- if (ret == 0) +- info("%s successfully initialized and connected.", desc->name); +- else +- info("%s error while loading driver (%d)", desc->name, ret); ++ error: ++ usb_set_intfdata(intf, NULL); ++ kfree(d); + return ret; + } + EXPORT_SYMBOL(dvb_usb_device_init); diff --git a/queue-5.4/media-dvb-usb-fix-use-after-free-access.patch b/queue-5.4/media-dvb-usb-fix-use-after-free-access.patch new file mode 100644 index 00000000000..0790a7b120b --- /dev/null +++ b/queue-5.4/media-dvb-usb-fix-use-after-free-access.patch @@ -0,0 +1,76 @@ +From c49206786ee252f28b7d4d155d1fff96f145a05d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 1 Feb 2021 09:32:47 +0100 +Subject: media: dvb-usb: Fix use-after-free access + +From: Takashi Iwai + +commit c49206786ee252f28b7d4d155d1fff96f145a05d upstream. + +dvb_usb_device_init() copies the properties to the own data, so that +the callers can release the original properties later (as done in the +commit 299c7007e936 ("media: dw2102: Fix memleak on sequence of +probes")). However, it also stores dev->desc pointer that is a +reference to the original properties data. Since dev->desc is +referred later, it may result in use-after-free, in the worst case, +leading to a kernel Oops as reported. + +This patch addresses the problem by allocating and copying the +properties at first, then get the desc from the copied properties. + +Reported-and-tested-by: Stefan Seyfried +BugLink: http://bugzilla.opensuse.org/show_bug.cgi?id=1181104 + +Reviewed-by: Robert Foss +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/dvb-usb/dvb-usb-init.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c ++++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c +@@ -267,27 +267,30 @@ int dvb_usb_device_init(struct usb_inter + if (du != NULL) + *du = NULL; + +- if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) { ++ d = kzalloc(sizeof(*d), GFP_KERNEL); ++ if (!d) { ++ err("no memory for 'struct dvb_usb_device'"); ++ return -ENOMEM; ++ } ++ ++ memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); ++ ++ desc = dvb_usb_find_device(udev, &d->props, &cold); ++ if (!desc) { + deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); +- return -ENODEV; ++ ret = -ENODEV; ++ goto error; + } + + if (cold) { + info("found a '%s' in cold state, will try to load a firmware", desc->name); + ret = dvb_usb_download_firmware(udev, props); + if (!props->no_reconnect || ret != 0) +- return ret; ++ goto error; + } + + info("found a '%s' in warm state.", desc->name); +- d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); +- if (d == NULL) { +- err("no memory for 'struct dvb_usb_device'"); +- return -ENOMEM; +- } +- + d->udev = udev; +- memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); + d->desc = desc; + d->owner = owner; + diff --git a/queue-5.4/media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch b/queue-5.4/media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch new file mode 100644 index 00000000000..01dc1dd77f0 --- /dev/null +++ b/queue-5.4/media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch @@ -0,0 +1,37 @@ +From bf9a40ae8d722f281a2721779595d6df1c33a0bf Mon Sep 17 00:00:00 2001 +From: Peilin Ye +Date: Fri, 11 Dec 2020 09:30:39 +0100 +Subject: media: dvbdev: Fix memory leak in dvb_media_device_free() + +From: Peilin Ye + +commit bf9a40ae8d722f281a2721779595d6df1c33a0bf upstream. + +dvb_media_device_free() is leaking memory. Free `dvbdev->adapter->conn` +before setting it to NULL, as documented in include/media/media-device.h: +"The media_entity instance itself must be freed explicitly by the driver +if required." + +Link: https://syzkaller.appspot.com/bug?id=9bbe4b842c98f0ed05c5eed77a226e9de33bf298 + +Link: https://lore.kernel.org/linux-media/20201211083039.521617-1-yepeilin.cs@gmail.com +Cc: stable@vger.kernel.org +Fixes: 0230d60e4661 ("[media] dvbdev: Add RF connector if needed") +Reported-by: syzbot+7f09440acc069a0d38ac@syzkaller.appspotmail.com +Signed-off-by: Peilin Ye +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/dvb-core/dvbdev.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -241,6 +241,7 @@ static void dvb_media_device_free(struct + + if (dvbdev->adapter->conn) { + media_device_unregister_entity(dvbdev->adapter->conn); ++ kfree(dvbdev->adapter->conn); + dvbdev->adapter->conn = NULL; + kfree(dvbdev->adapter->conn_pads); + dvbdev->adapter->conn_pads = NULL; diff --git a/queue-5.4/media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch b/queue-5.4/media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch new file mode 100644 index 00000000000..d10d8e47f47 --- /dev/null +++ b/queue-5.4/media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch @@ -0,0 +1,49 @@ +From 3630901933afba1d16c462b04d569b7576339223 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Mon, 15 Mar 2021 13:34:05 +0100 +Subject: media: staging/intel-ipu3: Fix memory leak in imu_fmt + +From: Ricardo Ribalda + +commit 3630901933afba1d16c462b04d569b7576339223 upstream. + +We are losing the reference to an allocated memory if try. Change the +order of the check to avoid that. + +Cc: stable@vger.kernel.org +Fixes: 6d5f26f2e045 ("media: staging/intel-ipu3-v4l: reduce kernel stack usage") +Signed-off-by: Ricardo Ribalda +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/media/ipu3/ipu3-v4l2.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/staging/media/ipu3/ipu3-v4l2.c ++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c +@@ -692,6 +692,13 @@ static int imgu_fmt(struct imgu_device * + if (inode == IMGU_NODE_STAT_3A || inode == IMGU_NODE_PARAMS) + continue; + ++ /* CSS expects some format on OUT queue */ ++ if (i != IPU3_CSS_QUEUE_OUT && ++ !imgu_pipe->nodes[inode].enabled) { ++ fmts[i] = NULL; ++ continue; ++ } ++ + if (try) { + fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, + sizeof(struct v4l2_pix_format_mplane), +@@ -704,10 +711,6 @@ static int imgu_fmt(struct imgu_device * + fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; + } + +- /* CSS expects some format on OUT queue */ +- if (i != IPU3_CSS_QUEUE_OUT && +- !imgu_pipe->nodes[inode].enabled) +- fmts[i] = NULL; + } + + if (!try) { diff --git a/queue-5.4/media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch b/queue-5.4/media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch new file mode 100644 index 00000000000..7e7b864adc4 --- /dev/null +++ b/queue-5.4/media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch @@ -0,0 +1,105 @@ +From dccfe2548746ca9cca3a20401ece4cf255d1f171 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Fri, 9 Apr 2021 10:41:35 +0200 +Subject: media: staging/intel-ipu3: Fix race condition during set_fmt + +From: Ricardo Ribalda + +commit dccfe2548746ca9cca3a20401ece4cf255d1f171 upstream. + +Do not modify imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, until the +format has been correctly validated. + +Otherwise, even if we use a backup variable, there is a period of time +where imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp might have an invalid +value that can be used by other functions. + +Cc: stable@vger.kernel.org +Fixes: ad91849996f9 ("media: staging/intel-ipu3: Fix set_fmt error handling") +Reviewed-by: Tomasz Figa +Signed-off-by: Ricardo Ribalda +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/media/ipu3/ipu3-v4l2.c | 30 ++++++++++++++---------------- + 1 file changed, 14 insertions(+), 16 deletions(-) + +--- a/drivers/staging/media/ipu3/ipu3-v4l2.c ++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c +@@ -668,7 +668,6 @@ static int imgu_fmt(struct imgu_device * + struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; +- struct v4l2_pix_format_mplane fmt_backup; + + dev_dbg(dev, "set fmt node [%u][%u](try = %u)", pipe, node, try); + +@@ -686,6 +685,7 @@ static int imgu_fmt(struct imgu_device * + + dev_dbg(dev, "IPU3 pipe %u pipe_id = %u", pipe, css_pipe->pipe_id); + ++ css_q = imgu_node_to_queue(node); + for (i = 0; i < IPU3_CSS_QUEUES; i++) { + unsigned int inode = imgu_map_node(imgu, i); + +@@ -700,6 +700,11 @@ static int imgu_fmt(struct imgu_device * + continue; + } + ++ if (i == css_q) { ++ fmts[i] = &f->fmt.pix_mp; ++ continue; ++ } ++ + if (try) { + fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, + sizeof(struct v4l2_pix_format_mplane), +@@ -728,39 +733,32 @@ static int imgu_fmt(struct imgu_device * + rects[IPU3_CSS_RECT_GDC]->height = pad_fmt.height; + } + +- /* +- * imgu doesn't set the node to the value given by user +- * before we return success from this function, so set it here. +- */ +- css_q = imgu_node_to_queue(node); + if (!fmts[css_q]) { + ret = -EINVAL; + goto out; + } +- fmt_backup = *fmts[css_q]; +- *fmts[css_q] = f->fmt.pix_mp; + + if (try) + ret = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe); + else + ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); + +- if (try || ret < 0) +- *fmts[css_q] = fmt_backup; +- + /* ret is the binary number in the firmware blob */ + if (ret < 0) + goto out; + +- if (try) +- f->fmt.pix_mp = *fmts[css_q]; +- else +- f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt; ++ /* ++ * imgu doesn't set the node to the value given by user ++ * before we return success from this function, so set it here. ++ */ ++ if (!try) ++ imgu_pipe->nodes[node].vdev_fmt.fmt.pix_mp = f->fmt.pix_mp; + + out: + if (try) { + for (i = 0; i < IPU3_CSS_QUEUES; i++) +- kfree(fmts[i]); ++ if (i != css_q) ++ kfree(fmts[i]); + } + + return ret; diff --git a/queue-5.4/media-staging-intel-ipu3-fix-set_fmt-error-handling.patch b/queue-5.4/media-staging-intel-ipu3-fix-set_fmt-error-handling.patch new file mode 100644 index 00000000000..f724f85f91d --- /dev/null +++ b/queue-5.4/media-staging-intel-ipu3-fix-set_fmt-error-handling.patch @@ -0,0 +1,57 @@ +From ad91849996f9dd79741a961fd03585a683b08356 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Wed, 10 Mar 2021 01:16:46 +0100 +Subject: media: staging/intel-ipu3: Fix set_fmt error handling + +From: Ricardo Ribalda + +commit ad91849996f9dd79741a961fd03585a683b08356 upstream. + +If there in an error during a set_fmt, do not overwrite the previous +sizes with the invalid config. + +Without this patch, v4l2-compliance ends up allocating 4GiB of RAM and +causing the following OOPs + +[ 38.662975] ipu3-imgu 0000:00:05.0: swiotlb buffer is full (sz: 4096 bytes) +[ 38.662980] DMA: Out of SW-IOMMU space for 4096 bytes at device 0000:00:05.0 +[ 38.663010] general protection fault: 0000 [#1] PREEMPT SMP + +Cc: stable@vger.kernel.org +Fixes: 6d5f26f2e045 ("media: staging/intel-ipu3-v4l: reduce kernel stack usage") +Signed-off-by: Ricardo Ribalda +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/media/ipu3/ipu3-v4l2.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/staging/media/ipu3/ipu3-v4l2.c ++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c +@@ -668,6 +668,7 @@ static int imgu_fmt(struct imgu_device * + struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; ++ struct v4l2_pix_format_mplane fmt_backup; + + dev_dbg(dev, "set fmt node [%u][%u](try = %u)", pipe, node, try); + +@@ -736,6 +737,7 @@ static int imgu_fmt(struct imgu_device * + ret = -EINVAL; + goto out; + } ++ fmt_backup = *fmts[css_q]; + *fmts[css_q] = f->fmt.pix_mp; + + if (try) +@@ -743,6 +745,9 @@ static int imgu_fmt(struct imgu_device * + else + ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); + ++ if (try || ret < 0) ++ *fmts[css_q] = fmt_backup; ++ + /* ret is the binary number in the firmware blob */ + if (ret < 0) + goto out; diff --git a/queue-5.4/rsi-use-resume_noirq-for-sdio.patch b/queue-5.4/rsi-use-resume_noirq-for-sdio.patch new file mode 100644 index 00000000000..8a49ac8c8e1 --- /dev/null +++ b/queue-5.4/rsi-use-resume_noirq-for-sdio.patch @@ -0,0 +1,46 @@ +From c434e5e48dc4e626364491455f97e2db0aa137b1 Mon Sep 17 00:00:00 2001 +From: Marek Vasut +Date: Sun, 28 Mar 2021 00:59:32 +0100 +Subject: rsi: Use resume_noirq for SDIO + +From: Marek Vasut + +commit c434e5e48dc4e626364491455f97e2db0aa137b1 upstream. + +The rsi_resume() does access the bus to enable interrupts on the RSI +SDIO WiFi card, however when calling sdio_claim_host() in the resume +path, it is possible the bus is already claimed and sdio_claim_host() +spins indefinitelly. Enable the SDIO card interrupts in resume_noirq +instead to prevent anything else from claiming the SDIO bus first. + +Fixes: 20db07332736 ("rsi: sdio suspend and resume support") +Signed-off-by: Marek Vasut +Cc: Amitkumar Karwar +Cc: Angus Ainslie +Cc: David S. Miller +Cc: Jakub Kicinski +Cc: Kalle Valo +Cc: Karun Eagalapati +Cc: Martin Kepplinger +Cc: Sebastian Krzyszkowiak +Cc: Siva Rebbagondla +Cc: netdev@vger.kernel.org +Cc: stable@vger.kernel.org +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20210327235932.175896-1-marex@denx.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/rsi/rsi_91x_sdio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c ++++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c +@@ -1511,7 +1511,7 @@ static int rsi_restore(struct device *de + } + static const struct dev_pm_ops rsi_pm_ops = { + .suspend = rsi_suspend, +- .resume = rsi_resume, ++ .resume_noirq = rsi_resume, + .freeze = rsi_freeze, + .thaw = rsi_thaw, + .restore = rsi_restore, diff --git a/queue-5.4/series b/queue-5.4/series index 0bdf88298f0..292042bc813 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -157,6 +157,22 @@ fuse-fix-write-deadlock.patch security-commoncap-fix-wstringop-overread-warning.patch fix-misc-new-gcc-warnings.patch jffs2-check-the-validity-of-dstlen-in-jffs2_zlib_compress.patch -smb3-when-mounting-with-multichannel-include-it-in-requested-capabilities.patch revert-337f13046ff0-futex-allow-futex_clock_realtime-with-futex_wait-op.patch x86-cpu-initialize-msr_tsc_aux-if-rdtscp-or-rdpid-is-supported.patch +kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch +ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch +ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch +ext4-fix-error-code-in-ext4_commit_super.patch +media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch +media-dvb-usb-fix-use-after-free-access.patch +media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch +media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch +media-staging-intel-ipu3-fix-set_fmt-error-handling.patch +media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch +usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch +usb-gadget-fix-double-free-of-device-descriptor-pointers.patch +usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch +usb-dwc3-gadget-fix-start_transfer-link-state-check.patch +usb-dwc2-fix-session-request-interrupt-handler.patch +tty-fix-memory-leak-in-vc_deallocate.patch +rsi-use-resume_noirq-for-sdio.patch diff --git a/queue-5.4/smb3-when-mounting-with-multichannel-include-it-in-requested-capabilities.patch b/queue-5.4/smb3-when-mounting-with-multichannel-include-it-in-requested-capabilities.patch deleted file mode 100644 index 3fb0e78b586..00000000000 --- a/queue-5.4/smb3-when-mounting-with-multichannel-include-it-in-requested-capabilities.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 679971e7213174efb56abc8fab1299d0a88db0e8 Mon Sep 17 00:00:00 2001 -From: Steve French -Date: Fri, 7 May 2021 18:24:11 -0500 -Subject: smb3: when mounting with multichannel include it in requested capabilities - -From: Steve French - -commit 679971e7213174efb56abc8fab1299d0a88db0e8 upstream. - -In the SMB3/SMB3.1.1 negotiate protocol request, we are supposed to -advertise CAP_MULTICHANNEL capability when establishing multiple -channels has been requested by the user doing the mount. See MS-SMB2 -sections 2.2.3 and 3.2.5.2 - -Without setting it there is some risk that multichannel could fail -if the server interpreted the field strictly. - -Reviewed-By: Tom Talpey -Reviewed-by: Shyam Prasad N -Cc: # v5.8+ -Signed-off-by: Steve French -Signed-off-by: Greg Kroah-Hartman ---- - fs/cifs/smb2pdu.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/fs/cifs/smb2pdu.c -+++ b/fs/cifs/smb2pdu.c -@@ -869,6 +869,8 @@ SMB2_negotiate(const unsigned int xid, s - req->SecurityMode = 0; - - req->Capabilities = cpu_to_le32(server->vals->req_capabilities); -+ if (ses->chan_max > 1) -+ req->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL); - - /* ClientGUID must be zero for SMB2.02 dialect */ - if (server->vals->protocol_id == SMB20_PROT_ID) -@@ -1055,6 +1057,9 @@ int smb3_validate_negotiate(const unsign - - pneg_inbuf->Capabilities = - cpu_to_le32(server->vals->req_capabilities); -+ if (tcon->ses->chan_max > 1) -+ pneg_inbuf->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL); -+ - memcpy(pneg_inbuf->Guid, server->client_guid, - SMB2_CLIENT_GUID_SIZE); - diff --git a/queue-5.4/tty-fix-memory-leak-in-vc_deallocate.patch b/queue-5.4/tty-fix-memory-leak-in-vc_deallocate.patch new file mode 100644 index 00000000000..f0868fceeeb --- /dev/null +++ b/queue-5.4/tty-fix-memory-leak-in-vc_deallocate.patch @@ -0,0 +1,34 @@ +From 211b4d42b70f1c1660feaa968dac0efc2a96ac4d Mon Sep 17 00:00:00 2001 +From: Pavel Skripkin +Date: Sun, 28 Mar 2021 00:44:43 +0300 +Subject: tty: fix memory leak in vc_deallocate + +From: Pavel Skripkin + +commit 211b4d42b70f1c1660feaa968dac0efc2a96ac4d upstream. + +syzbot reported memory leak in tty/vt. +The problem was in VT_DISALLOCATE ioctl cmd. +After allocating unimap with PIO_UNIMAP it wasn't +freed via VT_DISALLOCATE, but vc_cons[currcons].d was +zeroed. + +Reported-by: syzbot+bcc922b19ccc64240b42@syzkaller.appspotmail.com +Signed-off-by: Pavel Skripkin +Cc: stable +Link: https://lore.kernel.org/r/20210327214443.21548-1-paskripkin@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/vt/vt.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -1377,6 +1377,7 @@ struct vc_data *vc_deallocate(unsigned i + atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); + vcs_remove_sysfs(currcons); + visual_deinit(vc); ++ con_free_unimap(vc); + put_pid(vc->vt_pid); + vc_uniscr_set(vc, NULL); + kfree(vc->vc_screenbuf); diff --git a/queue-5.4/usb-dwc2-fix-session-request-interrupt-handler.patch b/queue-5.4/usb-dwc2-fix-session-request-interrupt-handler.patch new file mode 100644 index 00000000000..2d70665421c --- /dev/null +++ b/queue-5.4/usb-dwc2-fix-session-request-interrupt-handler.patch @@ -0,0 +1,47 @@ +From 42b32b164acecd850edef010915a02418345a033 Mon Sep 17 00:00:00 2001 +From: Artur Petrosyan +Date: Thu, 8 Apr 2021 13:45:49 +0400 +Subject: usb: dwc2: Fix session request interrupt handler + +From: Artur Petrosyan + +commit 42b32b164acecd850edef010915a02418345a033 upstream. + +According to programming guide in host mode, port +power must be turned on in session request +interrupt handlers. + +Fixes: 21795c826a45 ("usb: dwc2: exit hibernation on session request") +Cc: +Acked-by: Minas Harutyunyan +Signed-off-by: Artur Petrosyan +Link: https://lore.kernel.org/r/20210408094550.75484A0094@mailhost.synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/core_intr.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/usb/dwc2/core_intr.c ++++ b/drivers/usb/dwc2/core_intr.c +@@ -312,6 +312,7 @@ static void dwc2_handle_conn_id_status_c + static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) + { + int ret; ++ u32 hprt0; + + /* Clear interrupt */ + dwc2_writel(hsotg, GINTSTS_SESSREQINT, GINTSTS); +@@ -332,6 +333,13 @@ static void dwc2_handle_session_req_intr + * established + */ + dwc2_hsotg_disconnect(hsotg); ++ } else { ++ /* Turn on the port power bit. */ ++ hprt0 = dwc2_read_hprt0(hsotg); ++ hprt0 |= HPRT0_PWR; ++ dwc2_writel(hsotg, hprt0, HPRT0); ++ /* Connect hcd after port power is set. */ ++ dwc2_hcd_connect(hsotg); + } + } + diff --git a/queue-5.4/usb-dwc3-gadget-fix-start_transfer-link-state-check.patch b/queue-5.4/usb-dwc3-gadget-fix-start_transfer-link-state-check.patch new file mode 100644 index 00000000000..211e7103288 --- /dev/null +++ b/queue-5.4/usb-dwc3-gadget-fix-start_transfer-link-state-check.patch @@ -0,0 +1,63 @@ +From c560e76319a94a3b9285bc426c609903408e4826 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Mon, 19 Apr 2021 19:11:12 -0700 +Subject: usb: dwc3: gadget: Fix START_TRANSFER link state check + +From: Thinh Nguyen + +commit c560e76319a94a3b9285bc426c609903408e4826 upstream. + +The START_TRANSFER command needs to be executed while in ON/U0 link +state (with an exception during register initialization). Don't use +dwc->link_state to check this since the driver only tracks the link +state when the link state change interrupt is enabled. Check the link +state from DSTS register instead. + +Note that often the host already brings the device out of low power +before it sends/requests the next transfer. So, the user won't see any +issue when the device starts transfer then. This issue is more +noticeable in cases when the device delays starting transfer, which can +happen during delayed control status after the host put the device in +low power. + +Fixes: 799e9dc82968 ("usb: dwc3: gadget: conditionally disable Link State change events") +Cc: +Acked-by: Felipe Balbi +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/bcefaa9ecbc3e1936858c0baa14de6612960e909.1618884221.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -304,13 +304,12 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ + } + + if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) { +- int needs_wakeup; ++ int link_state; + +- needs_wakeup = (dwc->link_state == DWC3_LINK_STATE_U1 || +- dwc->link_state == DWC3_LINK_STATE_U2 || +- dwc->link_state == DWC3_LINK_STATE_U3); +- +- if (unlikely(needs_wakeup)) { ++ link_state = dwc3_gadget_get_link_state(dwc); ++ if (link_state == DWC3_LINK_STATE_U1 || ++ link_state == DWC3_LINK_STATE_U2 || ++ link_state == DWC3_LINK_STATE_U3) { + ret = __dwc3_gadget_wakeup(dwc); + dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n", + ret); +@@ -1862,6 +1861,8 @@ static int __dwc3_gadget_wakeup(struct d + case DWC3_LINK_STATE_RESET: + case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */ + case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */ ++ case DWC3_LINK_STATE_U2: /* in HS, means Sleep (L1) */ ++ case DWC3_LINK_STATE_U1: + case DWC3_LINK_STATE_RESUME: + break; + default: diff --git a/queue-5.4/usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch b/queue-5.4/usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch new file mode 100644 index 00000000000..4a5e41faf5f --- /dev/null +++ b/queue-5.4/usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch @@ -0,0 +1,90 @@ +From 4a5d797a9f9c4f18585544237216d7812686a71f Mon Sep 17 00:00:00 2001 +From: Anirudh Rayabharam +Date: Mon, 19 Apr 2021 09:07:08 +0530 +Subject: usb: gadget: dummy_hcd: fix gpf in gadget_setup + +From: Anirudh Rayabharam + +commit 4a5d797a9f9c4f18585544237216d7812686a71f upstream. + +Fix a general protection fault reported by syzbot due to a race between +gadget_setup() and gadget_unbind() in raw_gadget. + +The gadget core is supposed to guarantee that there won't be any more +callbacks to the gadget driver once the driver's unbind routine is +called. That guarantee is enforced in usb_gadget_remove_driver as +follows: + + usb_gadget_disconnect(udc->gadget); + if (udc->gadget->irq) + synchronize_irq(udc->gadget->irq); + udc->driver->unbind(udc->gadget); + usb_gadget_udc_stop(udc); + +usb_gadget_disconnect turns off the pullup resistor, telling the host +that the gadget is no longer connected and preventing the transmission +of any more USB packets. Any packets that have already been received +are sure to processed by the UDC driver's interrupt handler by the time +synchronize_irq returns. + +But this doesn't work with dummy_hcd, because dummy_hcd doesn't use +interrupts; it uses a timer instead. It does have code to emulate the +effect of synchronize_irq, but that code doesn't get invoked at the +right time -- it currently runs in usb_gadget_udc_stop, after the unbind +callback instead of before. Indeed, there's no way for +usb_gadget_remove_driver to invoke this code before the unbind callback. + +To fix this, move the synchronize_irq() emulation code to dummy_pullup +so that it runs before unbind. Also, add a comment explaining why it is +necessary to have it there. + +Reported-by: syzbot+eb4674092e6cc8d9e0bd@syzkaller.appspotmail.com +Suggested-by: Alan Stern +Acked-by: Alan Stern +Signed-off-by: Anirudh Rayabharam +Link: https://lore.kernel.org/r/20210419033713.3021-1-mail@anirudhrb.com +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/dummy_hcd.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -900,6 +900,21 @@ static int dummy_pullup(struct usb_gadge + spin_lock_irqsave(&dum->lock, flags); + dum->pullup = (value != 0); + set_link_state(dum_hcd); ++ if (value == 0) { ++ /* ++ * Emulate synchronize_irq(): wait for callbacks to finish. ++ * This seems to be the best place to emulate the call to ++ * synchronize_irq() that's in usb_gadget_remove_driver(). ++ * Doing it in dummy_udc_stop() would be too late since it ++ * is called after the unbind callback and unbind shouldn't ++ * be invoked until all the other callbacks are finished. ++ */ ++ while (dum->callback_usage > 0) { ++ spin_unlock_irqrestore(&dum->lock, flags); ++ usleep_range(1000, 2000); ++ spin_lock_irqsave(&dum->lock, flags); ++ } ++ } + spin_unlock_irqrestore(&dum->lock, flags); + + usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd)); +@@ -1001,14 +1016,6 @@ static int dummy_udc_stop(struct usb_gad + spin_lock_irq(&dum->lock); + dum->ints_enabled = 0; + stop_activity(dum); +- +- /* emulate synchronize_irq(): wait for callbacks to finish */ +- while (dum->callback_usage > 0) { +- spin_unlock_irq(&dum->lock); +- usleep_range(1000, 2000); +- spin_lock_irq(&dum->lock); +- } +- + dum->driver = NULL; + spin_unlock_irq(&dum->lock); + diff --git a/queue-5.4/usb-gadget-fix-double-free-of-device-descriptor-pointers.patch b/queue-5.4/usb-gadget-fix-double-free-of-device-descriptor-pointers.patch new file mode 100644 index 00000000000..091cdd2401a --- /dev/null +++ b/queue-5.4/usb-gadget-fix-double-free-of-device-descriptor-pointers.patch @@ -0,0 +1,44 @@ +From 43c4cab006f55b6ca549dd1214e22f5965a8675f Mon Sep 17 00:00:00 2001 +From: Hemant Kumar +Date: Wed, 21 Apr 2021 12:47:32 -0700 +Subject: usb: gadget: Fix double free of device descriptor pointers + +From: Hemant Kumar + +commit 43c4cab006f55b6ca549dd1214e22f5965a8675f upstream. + +Upon driver unbind usb_free_all_descriptors() function frees all +speed descriptor pointers without setting them to NULL. In case +gadget speed changes (i.e from super speed plus to super speed) +after driver unbind only upto super speed descriptor pointers get +populated. Super speed plus desc still holds the stale (already +freed) pointer. Fix this issue by setting all descriptor pointers +to NULL after freeing them in usb_free_all_descriptors(). + +Fixes: f5c61225cf29 ("usb: gadget: Update function for SuperSpeedPlus") +cc: stable@vger.kernel.org +Reviewed-by: Peter Chen +Signed-off-by: Hemant Kumar +Signed-off-by: Wesley Cheng +Link: https://lore.kernel.org/r/1619034452-17334-1-git-send-email-wcheng@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/config.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/gadget/config.c ++++ b/drivers/usb/gadget/config.c +@@ -194,9 +194,13 @@ EXPORT_SYMBOL_GPL(usb_assign_descriptors + void usb_free_all_descriptors(struct usb_function *f) + { + usb_free_descriptors(f->fs_descriptors); ++ f->fs_descriptors = NULL; + usb_free_descriptors(f->hs_descriptors); ++ f->hs_descriptors = NULL; + usb_free_descriptors(f->ss_descriptors); ++ f->ss_descriptors = NULL; + usb_free_descriptors(f->ssp_descriptors); ++ f->ssp_descriptors = NULL; + } + EXPORT_SYMBOL_GPL(usb_free_all_descriptors); + diff --git a/queue-5.4/usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch b/queue-5.4/usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch new file mode 100644 index 00000000000..2cc12d67b17 --- /dev/null +++ b/queue-5.4/usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch @@ -0,0 +1,44 @@ +From 55b74ce7d2ce0b0058f3e08cab185a0afacfe39e Mon Sep 17 00:00:00 2001 +From: Dean Anderson +Date: Wed, 17 Mar 2021 15:41:09 -0700 +Subject: usb: gadget/function/f_fs string table fix for multiple languages + +From: Dean Anderson + +commit 55b74ce7d2ce0b0058f3e08cab185a0afacfe39e upstream. + +Fixes bug with the handling of more than one language in +the string table in f_fs.c. +str_count was not reset for subsequent language codes. +str_count-- "rolls under" and processes u32 max strings on +the processing of the second language entry. +The existing bug can be reproduced by adding a second language table +to the structure "strings" in tools/usb/ffs-test.c. + +Signed-off-by: Dean Anderson +Link: https://lore.kernel.org/r/20210317224109.21534-1-dean@sensoray.com +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_fs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -2658,6 +2658,7 @@ static int __ffs_data_got_strings(struct + + do { /* lang_count > 0 so we can use do-while */ + unsigned needed = needed_count; ++ u32 str_per_lang = str_count; + + if (unlikely(len < 3)) + goto error_free; +@@ -2693,7 +2694,7 @@ static int __ffs_data_got_strings(struct + + data += length + 1; + len -= length + 1; +- } while (--str_count); ++ } while (--str_per_lang); + + s->id = 0; /* terminator */ + s->s = NULL; -- 2.47.3