From: Sasha Levin Date: Tue, 20 Aug 2024 11:58:53 +0000 (-0400) Subject: Fixes for 5.10 X-Git-Tag: v6.1.107~106 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=748b0ebfad4a0589667114d75497edc2fc940dc8;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/binfmt_misc-cleanup-on-filesystem-umount.patch b/queue-5.10/binfmt_misc-cleanup-on-filesystem-umount.patch new file mode 100644 index 00000000000..57e21ce10a3 --- /dev/null +++ b/queue-5.10/binfmt_misc-cleanup-on-filesystem-umount.patch @@ -0,0 +1,442 @@ +From d9f8507a2a1e05d533695358337c0c38910af991 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Oct 2021 12:31:13 +0200 +Subject: binfmt_misc: cleanup on filesystem umount + +From: Christian Brauner + +[ Upstream commit 1c5976ef0f7ad76319df748ccb99a4c7ba2ba464 ] + +Currently, registering a new binary type pins the binfmt_misc +filesystem. Specifically, this means that as long as there is at least +one binary type registered the binfmt_misc filesystem survives all +umounts, i.e. the superblock is not destroyed. Meaning that a umount +followed by another mount will end up with the same superblock and the +same binary type handlers. This is a behavior we tend to discourage for +any new filesystems (apart from a few special filesystems such as e.g. +configfs or debugfs). A umount operation without the filesystem being +pinned - by e.g. someone holding a file descriptor to an open file - +should usually result in the destruction of the superblock and all +associated resources. This makes introspection easier and leads to +clearly defined, simple and clean semantics. An administrator can rely +on the fact that a umount will guarantee a clean slate making it +possible to reinitialize a filesystem. Right now all binary types would +need to be explicitly deleted before that can happen. + +This allows us to remove the heavy-handed calls to simple_pin_fs() and +simple_release_fs() when creating and deleting binary types. This in +turn allows us to replace the current brittle pinning mechanism abusing +dget() which has caused a range of bugs judging from prior fixes in [2] +and [3]. The additional dget() in load_misc_binary() pins the dentry but +only does so for the sake to prevent ->evict_inode() from freeing the +node when a user removes the binary type and kill_node() is run. Which +would mean ->interpreter and ->interp_file would be freed causing a UAF. + +This isn't really nicely documented nor is it very clean because it +relies on simple_pin_fs() pinning the filesystem as long as at least one +binary type exists. Otherwise it would cause load_misc_binary() to hold +on to a dentry belonging to a superblock that has been shutdown. +Replace that implicit pinning with a clean and simple per-node refcount +and get rid of the ugly dget() pinning. A similar mechanism exists for +e.g. binderfs (cf. [4]). All the cleanup work can now be done in +->evict_inode(). + +In a follow-up patch we will make it possible to use binfmt_misc in +sandboxes. We will use the cleaner semantics where a umount for the +filesystem will cause the superblock and all resources to be +deallocated. In preparation for this apply the same semantics to the +initial binfmt_misc mount. Note, that this is a user-visible change and +as such a uapi change but one that we can reasonably risk. We've +discussed this in earlier versions of this patchset (cf. [1]). + +The main user and provider of binfmt_misc is systemd. Systemd provides +binfmt_misc via autofs since it is configurable as a kernel module and +is used by a few exotic packages and users. As such a binfmt_misc mount +is triggered when /proc/sys/fs/binfmt_misc is accessed and is only +provided on demand. Other autofs on demand filesystems include EFI ESP +which systemd umounts if the mountpoint stays idle for a certain amount +of time. This doesn't apply to the binfmt_misc autofs mount which isn't +touched once it is mounted meaning this change can't accidently wipe +binary type handlers without someone having explicitly unmounted +binfmt_misc. After speaking to systemd folks they don't expect this +change to affect them. + +In line with our general policy, if we see a regression for systemd or +other users with this change we will switch back to the old behavior for +the initial binfmt_misc mount and have binary types pin the filesystem +again. But while we touch this code let's take the chance and let's +improve on the status quo. + +[1]: https://lore.kernel.org/r/20191216091220.465626-2-laurent@vivier.eu +[2]: commit 43a4f2619038 ("exec: binfmt_misc: fix race between load_misc_binary() and kill_node()" +[3]: commit 83f918274e4b ("exec: binfmt_misc: shift filp_close(interp_file) from kill_node() to bm_evict_inode()") +[4]: commit f0fe2c0f050d ("binder: prevent UAF for binderfs devices II") + +Link: https://lore.kernel.org/r/20211028103114.2849140-1-brauner@kernel.org (v1) +Cc: Sargun Dhillon +Cc: Serge Hallyn +Cc: Jann Horn +Cc: Henning Schild +Cc: Andrei Vagin +Cc: Al Viro +Cc: Laurent Vivier +Cc: linux-fsdevel@vger.kernel.org +Acked-by: Serge Hallyn +Signed-off-by: Christian Brauner +Signed-off-by: Christian Brauner +Signed-off-by: Kees Cook +--- +/* v2 */ +- Christian Brauner : + - Add more comments that explain what's going on. + - Rename functions while changing them to better reflect what they are + doing to make the code easier to understand. + - In the first version when a specific binary type handler was removed + either through a write to the entry's file or all binary type + handlers were removed by a write to the binfmt_misc mount's status + file all cleanup work happened during inode eviction. + That includes removal of the relevant entries from entry list. While + that works fine I disliked that model after thinking about it for a + bit. Because it means that there was a window were someone has + already removed a or all binary handlers but they could still be + safely reached from load_misc_binary() when it has managed to take + the read_lock() on the entries list while inode eviction was already + happening. Again, that perfectly benign but it's cleaner to remove + the binary handler from the list immediately meaning that ones the + write to then entry's file or the binfmt_misc status file returns + the binary type cannot be executed anymore. That gives stronger + guarantees to the user. +Signed-off-by: Sasha Levin +--- + fs/binfmt_misc.c | 216 ++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 168 insertions(+), 48 deletions(-) + +diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c +index ce0047feea729..744ae53d483db 100644 +--- a/fs/binfmt_misc.c ++++ b/fs/binfmt_misc.c +@@ -60,12 +60,11 @@ typedef struct { + char *name; + struct dentry *dentry; + struct file *interp_file; ++ refcount_t users; /* sync removal with load_misc_binary() */ + } Node; + + static DEFINE_RWLOCK(entries_lock); + static struct file_system_type bm_fs_type; +-static struct vfsmount *bm_mnt; +-static int entry_count; + + /* + * Max length of the register string. Determined by: +@@ -82,19 +81,23 @@ static int entry_count; + */ + #define MAX_REGISTER_LENGTH 1920 + +-/* +- * Check if we support the binfmt +- * if we do, return the node, else NULL +- * locking is done in load_misc_binary ++/** ++ * search_binfmt_handler - search for a binary handler for @bprm ++ * @misc: handle to binfmt_misc instance ++ * @bprm: binary for which we are looking for a handler ++ * ++ * Search for a binary type handler for @bprm in the list of registered binary ++ * type handlers. ++ * ++ * Return: binary type list entry on success, NULL on failure + */ +-static Node *check_file(struct linux_binprm *bprm) ++static Node *search_binfmt_handler(struct linux_binprm *bprm) + { + char *p = strrchr(bprm->interp, '.'); +- struct list_head *l; ++ Node *e; + + /* Walk all the registered handlers. */ +- list_for_each(l, &entries) { +- Node *e = list_entry(l, Node, list); ++ list_for_each_entry(e, &entries, list) { + char *s; + int j; + +@@ -123,9 +126,49 @@ static Node *check_file(struct linux_binprm *bprm) + if (j == e->size) + return e; + } ++ + return NULL; + } + ++/** ++ * get_binfmt_handler - try to find a binary type handler ++ * @misc: handle to binfmt_misc instance ++ * @bprm: binary for which we are looking for a handler ++ * ++ * Try to find a binfmt handler for the binary type. If one is found take a ++ * reference to protect against removal via bm_{entry,status}_write(). ++ * ++ * Return: binary type list entry on success, NULL on failure ++ */ ++static Node *get_binfmt_handler(struct linux_binprm *bprm) ++{ ++ Node *e; ++ ++ read_lock(&entries_lock); ++ e = search_binfmt_handler(bprm); ++ if (e) ++ refcount_inc(&e->users); ++ read_unlock(&entries_lock); ++ return e; ++} ++ ++/** ++ * put_binfmt_handler - put binary handler node ++ * @e: node to put ++ * ++ * Free node syncing with load_misc_binary() and defer final free to ++ * load_misc_binary() in case it is using the binary type handler we were ++ * requested to remove. ++ */ ++static void put_binfmt_handler(Node *e) ++{ ++ if (refcount_dec_and_test(&e->users)) { ++ if (e->flags & MISC_FMT_OPEN_FILE) ++ filp_close(e->interp_file, NULL); ++ kfree(e); ++ } ++} ++ + /* + * the loader itself + */ +@@ -139,12 +182,7 @@ static int load_misc_binary(struct linux_binprm *bprm) + if (!enabled) + return retval; + +- /* to keep locking time low, we copy the interpreter string */ +- read_lock(&entries_lock); +- fmt = check_file(bprm); +- if (fmt) +- dget(fmt->dentry); +- read_unlock(&entries_lock); ++ fmt = get_binfmt_handler(bprm); + if (!fmt) + return retval; + +@@ -196,7 +234,16 @@ static int load_misc_binary(struct linux_binprm *bprm) + + retval = 0; + ret: +- dput(fmt->dentry); ++ ++ /* ++ * If we actually put the node here all concurrent calls to ++ * load_misc_binary() will have finished. We also know ++ * that for the refcount to be zero ->evict_inode() must have removed ++ * the node to be deleted from the list. All that is left for us is to ++ * close and free. ++ */ ++ put_binfmt_handler(fmt); ++ + return retval; + } + +@@ -551,30 +598,90 @@ static struct inode *bm_get_inode(struct super_block *sb, int mode) + return inode; + } + ++/** ++ * bm_evict_inode - cleanup data associated with @inode ++ * @inode: inode to which the data is attached ++ * ++ * Cleanup the binary type handler data associated with @inode if a binary type ++ * entry is removed or the filesystem is unmounted and the super block is ++ * shutdown. ++ * ++ * If the ->evict call was not caused by a super block shutdown but by a write ++ * to remove the entry or all entries via bm_{entry,status}_write() the entry ++ * will have already been removed from the list. We keep the list_empty() check ++ * to make that explicit. ++*/ + static void bm_evict_inode(struct inode *inode) + { + Node *e = inode->i_private; + +- if (e && e->flags & MISC_FMT_OPEN_FILE) +- filp_close(e->interp_file, NULL); +- + clear_inode(inode); +- kfree(e); ++ ++ if (e) { ++ write_lock(&entries_lock); ++ if (!list_empty(&e->list)) ++ list_del_init(&e->list); ++ write_unlock(&entries_lock); ++ put_binfmt_handler(e); ++ } + } + +-static void kill_node(Node *e) ++/** ++ * unlink_binfmt_dentry - remove the dentry for the binary type handler ++ * @dentry: dentry associated with the binary type handler ++ * ++ * Do the actual filesystem work to remove a dentry for a registered binary ++ * type handler. Since binfmt_misc only allows simple files to be created ++ * directly under the root dentry of the filesystem we ensure that we are ++ * indeed passed a dentry directly beneath the root dentry, that the inode ++ * associated with the root dentry is locked, and that it is a regular file we ++ * are asked to remove. ++ */ ++static void unlink_binfmt_dentry(struct dentry *dentry) + { +- struct dentry *dentry; ++ struct dentry *parent = dentry->d_parent; ++ struct inode *inode, *parent_inode; ++ ++ /* All entries are immediate descendants of the root dentry. */ ++ if (WARN_ON_ONCE(dentry->d_sb->s_root != parent)) ++ return; + ++ /* We only expect to be called on regular files. */ ++ inode = d_inode(dentry); ++ if (WARN_ON_ONCE(!S_ISREG(inode->i_mode))) ++ return; ++ ++ /* The parent inode must be locked. */ ++ parent_inode = d_inode(parent); ++ if (WARN_ON_ONCE(!inode_is_locked(parent_inode))) ++ return; ++ ++ if (simple_positive(dentry)) { ++ dget(dentry); ++ simple_unlink(parent_inode, dentry); ++ d_delete(dentry); ++ dput(dentry); ++ } ++} ++ ++/** ++ * remove_binfmt_handler - remove a binary type handler ++ * @misc: handle to binfmt_misc instance ++ * @e: binary type handler to remove ++ * ++ * Remove a binary type handler from the list of binary type handlers and ++ * remove its associated dentry. This is called from ++ * binfmt_{entry,status}_write(). In the future, we might want to think about ++ * adding a proper ->unlink() method to binfmt_misc instead of forcing caller's ++ * to use writes to files in order to delete binary type handlers. But it has ++ * worked for so long that it's not a pressing issue. ++ */ ++static void remove_binfmt_handler(Node *e) ++{ + write_lock(&entries_lock); + list_del_init(&e->list); + write_unlock(&entries_lock); +- +- dentry = e->dentry; +- drop_nlink(d_inode(dentry)); +- d_drop(dentry); +- dput(dentry); +- simple_release_fs(&bm_mnt, &entry_count); ++ unlink_binfmt_dentry(e->dentry); + } + + /* / */ +@@ -601,8 +708,8 @@ bm_entry_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) + static ssize_t bm_entry_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) + { +- struct dentry *root; +- Node *e = file_inode(file)->i_private; ++ struct inode *inode = file_inode(file); ++ Node *e = inode->i_private; + int res = parse_command(buffer, count); + + switch (res) { +@@ -616,13 +723,22 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer, + break; + case 3: + /* Delete this handler. */ +- root = file_inode(file)->i_sb->s_root; +- inode_lock(d_inode(root)); ++ inode = d_inode(inode->i_sb->s_root); ++ inode_lock(inode); + ++ /* ++ * In order to add new element or remove elements from the list ++ * via bm_{entry,register,status}_write() inode_lock() on the ++ * root inode must be held. ++ * The lock is exclusive ensuring that the list can't be ++ * modified. Only load_misc_binary() can access but does so ++ * read-only. So we only need to take the write lock when we ++ * actually remove the entry from the list. ++ */ + if (!list_empty(&e->list)) +- kill_node(e); ++ remove_binfmt_handler(e); + +- inode_unlock(d_inode(root)); ++ inode_unlock(inode); + break; + default: + return res; +@@ -681,13 +797,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, + if (!inode) + goto out2; + +- err = simple_pin_fs(&bm_fs_type, &bm_mnt, &entry_count); +- if (err) { +- iput(inode); +- inode = NULL; +- goto out2; +- } +- ++ refcount_set(&e->users, 1); + e->dentry = dget(dentry); + inode->i_private = e; + inode->i_fop = &bm_entry_operations; +@@ -731,7 +841,8 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) + { + int res = parse_command(buffer, count); +- struct dentry *root; ++ Node *e, *next; ++ struct inode *inode; + + switch (res) { + case 1: +@@ -744,13 +855,22 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer, + break; + case 3: + /* Delete all handlers. */ +- root = file_inode(file)->i_sb->s_root; +- inode_lock(d_inode(root)); ++ inode = d_inode(file_inode(file)->i_sb->s_root); ++ inode_lock(inode); + +- while (!list_empty(&entries)) +- kill_node(list_first_entry(&entries, Node, list)); ++ /* ++ * In order to add new element or remove elements from the list ++ * via bm_{entry,register,status}_write() inode_lock() on the ++ * root inode must be held. ++ * The lock is exclusive ensuring that the list can't be ++ * modified. Only load_misc_binary() can access but does so ++ * read-only. So we only need to take the write lock when we ++ * actually remove the entry from the list. ++ */ ++ list_for_each_entry_safe(e, next, &entries, list) ++ remove_binfmt_handler(e); + +- inode_unlock(d_inode(root)); ++ inode_unlock(inode); + break; + default: + return res; +-- +2.43.0 + diff --git a/queue-5.10/drm-amd-display-validate-hw_points_num-before-using-.patch b/queue-5.10/drm-amd-display-validate-hw_points_num-before-using-.patch new file mode 100644 index 00000000000..82ec6ccea08 --- /dev/null +++ b/queue-5.10/drm-amd-display-validate-hw_points_num-before-using-.patch @@ -0,0 +1,42 @@ +From fa06baedd55527d29538a286836f72b1d4bc5aac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Jul 2023 18:23:58 -0600 +Subject: drm/amd/display: Validate hw_points_num before using it + +From: Alex Hung + +[ Upstream commit 58c3b3341cea4f75dc8c003b89f8a6dd8ec55e50 ] + +[WHAT] +hw_points_num is 0 before ogam LUT is programmed; however, function +"dwb3_program_ogam_pwl" assumes hw_points_num is always greater than 0, +i.e. substracting it by 1 as an array index. + +[HOW] +Check hw_points_num is not equal to 0 before using it. + +Reviewed-by: Harry Wentland +Signed-off-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c +index 6d621f07be489..1c170fbb634da 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dwb_cm.c +@@ -243,6 +243,9 @@ static bool dwb3_program_ogam_lut( + return false; + } + ++ if (params->hw_points_num == 0) ++ return false; ++ + REG_SET(DWB_OGAM_CONTROL, 0, DWB_OGAM_MODE, 2); + + current_mode = dwb3_get_ogam_current(dwbc30); +-- +2.43.0 + diff --git a/queue-5.10/gfs2-setattr_chown-add-missing-initialization.patch b/queue-5.10/gfs2-setattr_chown-add-missing-initialization.patch new file mode 100644 index 00000000000..01c7a2b670a --- /dev/null +++ b/queue-5.10/gfs2-setattr_chown-add-missing-initialization.patch @@ -0,0 +1,34 @@ +From 2eb753cb71b0e45a97c3322109169d2e49e1f29d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 21 Oct 2023 20:51:13 +0200 +Subject: gfs2: setattr_chown: Add missing initialization + +From: Andreas Gruenbacher + +[ Upstream commit 2d8d7990619878a848b1d916c2f936d3012ee17d ] + +Add a missing initialization of variable ap in setattr_chown(). +Without, chown() may be able to bypass quotas. + +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index d75d56d9ea0ca..22905a076a6a2 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -1905,7 +1905,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) + kuid_t ouid, nuid; + kgid_t ogid, ngid; + int error; +- struct gfs2_alloc_parms ap; ++ struct gfs2_alloc_parms ap = {}; + + ouid = inode->i_uid; + ogid = inode->i_gid; +-- +2.43.0 + diff --git a/queue-5.10/i2c-riic-avoid-potential-division-by-zero.patch b/queue-5.10/i2c-riic-avoid-potential-division-by-zero.patch new file mode 100644 index 00000000000..44494797780 --- /dev/null +++ b/queue-5.10/i2c-riic-avoid-potential-division-by-zero.patch @@ -0,0 +1,35 @@ +From 7ed3443c2faca24e9316d1f009a7413951e20e88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 22:00:23 +0200 +Subject: i2c: riic: avoid potential division by zero + +From: Wolfram Sang + +[ Upstream commit 7890fce6201aed46d3576e3d641f9ee5c1f0e16f ] + +Value comes from DT, so it could be 0. Unlikely, but could be. + +Signed-off-by: Wolfram Sang +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-riic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c +index 4eccc0f69861f..d8f252c4caf2b 100644 +--- a/drivers/i2c/busses/i2c-riic.c ++++ b/drivers/i2c/busses/i2c-riic.c +@@ -312,7 +312,7 @@ static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t) + * frequency with only 62 clock ticks max (31 high, 31 low). + * Aim for a duty of 60% LOW, 40% HIGH. + */ +- total_ticks = DIV_ROUND_UP(rate, t->bus_freq_hz); ++ total_ticks = DIV_ROUND_UP(rate, t->bus_freq_hz ?: 1); + + for (cks = 0; cks < 7; cks++) { + /* +-- +2.43.0 + diff --git a/queue-5.10/ib-hfi1-fix-potential-deadlock-on-irq_src_lock-and-d.patch b/queue-5.10/ib-hfi1-fix-potential-deadlock-on-irq_src_lock-and-d.patch new file mode 100644 index 00000000000..38d57ed8fbe --- /dev/null +++ b/queue-5.10/ib-hfi1-fix-potential-deadlock-on-irq_src_lock-and-d.patch @@ -0,0 +1,77 @@ +From 6fc8af0fda939ea5107cd9c9539a6c134b370788 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 10:11:16 +0000 +Subject: IB/hfi1: Fix potential deadlock on &irq_src_lock and &dd->uctxt_lock + +From: Chengfeng Ye + +[ Upstream commit 2f19c4b8395ccb6eb25ccafee883c8cfbe3fc193 ] + +handle_receive_interrupt_napi_sp() running inside interrupt handler +could introduce inverse lock ordering between &dd->irq_src_lock +and &dd->uctxt_lock, if read_mod_write() is preempted by the isr. + + [CPU0] | [CPU1] +hfi1_ipoib_dev_open() | +--> hfi1_netdev_enable_queues() | +--> enable_queues(rx) | +--> hfi1_rcvctrl() | +--> set_intr_bits() | +--> read_mod_write() | +--> spin_lock(&dd->irq_src_lock) | + | hfi1_poll() + | --> poll_next() + | --> spin_lock_irq(&dd->uctxt_lock) + | + | --> hfi1_rcvctrl() + | --> set_intr_bits() + | --> read_mod_write() + | --> spin_lock(&dd->irq_src_lock) + | + --> handle_receive_interrupt_napi_sp() | + --> set_all_fastpath() | + --> hfi1_rcd_get_by_index() | + --> spin_lock_irqsave(&dd->uctxt_lock) | + +This flaw was found by an experimental static analysis tool I am +developing for irq-related deadlock. + +To prevent the potential deadlock, the patch use spin_lock_irqsave() +on &dd->irq_src_lock inside read_mod_write() to prevent the possible +deadlock scenario. + +Signed-off-by: Chengfeng Ye +Link: https://lore.kernel.org/r/20230926101116.2797-1-dg573847474@gmail.com +Acked-by: Dennis Dalessandro +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/hfi1/chip.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c +index c74868f016379..b7ae4bf2f5499 100644 +--- a/drivers/infiniband/hw/hfi1/chip.c ++++ b/drivers/infiniband/hw/hfi1/chip.c +@@ -13224,15 +13224,16 @@ static void read_mod_write(struct hfi1_devdata *dd, u16 src, u64 bits, + { + u64 reg; + u16 idx = src / BITS_PER_REGISTER; ++ unsigned long flags; + +- spin_lock(&dd->irq_src_lock); ++ spin_lock_irqsave(&dd->irq_src_lock, flags); + reg = read_csr(dd, CCE_INT_MASK + (8 * idx)); + if (set) + reg |= bits; + else + reg &= ~bits; + write_csr(dd, CCE_INT_MASK + (8 * idx), reg); +- spin_unlock(&dd->irq_src_lock); ++ spin_unlock_irqrestore(&dd->irq_src_lock, flags); + } + + /** +-- +2.43.0 + diff --git a/queue-5.10/media-qcom-venus-fix-incorrect-return-value.patch b/queue-5.10/media-qcom-venus-fix-incorrect-return-value.patch new file mode 100644 index 00000000000..e8ad3195280 --- /dev/null +++ b/queue-5.10/media-qcom-venus-fix-incorrect-return-value.patch @@ -0,0 +1,37 @@ +From 7c69f0925daa7e6120436f4145544b5c7c7affa4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Oct 2023 12:08:47 +0200 +Subject: media: qcom: venus: fix incorrect return value + +From: Hans Verkuil + +[ Upstream commit 51b74c09ac8c5862007fc2bf0d465529d06dd446 ] + +'pd' can be NULL, and in that case it shouldn't be passed to +PTR_ERR. Fixes a smatch warning: + +drivers/media/platform/qcom/venus/pm_helpers.c:873 vcodec_domains_get() warn: passing zero to 'PTR_ERR' + +Signed-off-by: Hans Verkuil +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Sasha Levin +--- + drivers/media/platform/qcom/venus/pm_helpers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c +index 6bf9c5c319de7..fd55352d743ee 100644 +--- a/drivers/media/platform/qcom/venus/pm_helpers.c ++++ b/drivers/media/platform/qcom/venus/pm_helpers.c +@@ -765,7 +765,7 @@ static int vcodec_domains_get(struct venus_core *core) + pd = dev_pm_domain_attach_by_name(dev, + res->vcodec_pmdomains[i]); + if (IS_ERR_OR_NULL(pd)) +- return PTR_ERR(pd) ? : -ENODATA; ++ return pd ? PTR_ERR(pd) : -ENODATA; + core->pmdomains[i] = pd; + } + +-- +2.43.0 + diff --git a/queue-5.10/media-radio-isa-use-dev_name-to-fill-in-bus_info.patch b/queue-5.10/media-radio-isa-use-dev_name-to-fill-in-bus_info.patch new file mode 100644 index 00000000000..52a28816d28 --- /dev/null +++ b/queue-5.10/media-radio-isa-use-dev_name-to-fill-in-bus_info.patch @@ -0,0 +1,41 @@ +From a7a0c06a3479b9b9f6fa6fef70107d53a05660ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 23 Sep 2023 17:21:04 +0200 +Subject: media: radio-isa: use dev_name to fill in bus_info + +From: Hans Verkuil + +[ Upstream commit 8b7f3cf4eb9a95940eaabad3226caeaa0d9aa59d ] + +This fixes this warning: + +drivers/media/radio/radio-isa.c: In function 'radio_isa_querycap': +drivers/media/radio/radio-isa.c:39:57: warning: '%s' directive output may be truncated writing up to 35 bytes into a region of size 28 [-Wformat-truncation=] + 39 | snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name); + | ^~ +drivers/media/radio/radio-isa.c:39:9: note: 'snprintf' output between 5 and 40 bytes into a destination of size 32 + 39 | snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/radio/radio-isa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/radio/radio-isa.c b/drivers/media/radio/radio-isa.c +index ad2ac16ff12dd..610d3e3269518 100644 +--- a/drivers/media/radio/radio-isa.c ++++ b/drivers/media/radio/radio-isa.c +@@ -36,7 +36,7 @@ static int radio_isa_querycap(struct file *file, void *priv, + + strscpy(v->driver, isa->drv->driver.driver.name, sizeof(v->driver)); + strscpy(v->card, isa->drv->card, sizeof(v->card)); +- snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name); ++ snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", dev_name(isa->v4l2_dev.dev)); + return 0; + } + +-- +2.43.0 + diff --git a/queue-5.10/rdma-rtrs-fix-the-problem-of-variable-not-initialize.patch b/queue-5.10/rdma-rtrs-fix-the-problem-of-variable-not-initialize.patch new file mode 100644 index 00000000000..c08d27116de --- /dev/null +++ b/queue-5.10/rdma-rtrs-fix-the-problem-of-variable-not-initialize.patch @@ -0,0 +1,36 @@ +From 8255300dcef6535415ce431079863bdca7b9048d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 10:08:06 +0800 +Subject: RDMA/rtrs: Fix the problem of variable not initialized fully + +From: Zhu Yanjun + +[ Upstream commit c5930a1aa08aafe6ffe15b5d28fe875f88f6ac86 ] + +No functionality change. The variable which is not initialized fully +will introduce potential risks. + +Signed-off-by: Zhu Yanjun +Link: https://lore.kernel.org/r/20230919020806.534183-1-yanjun.zhu@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c +index 76b993e8d672f..f34793068f344 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs.c +@@ -235,7 +235,7 @@ static int create_cq(struct rtrs_con *con, int cq_vector, u16 cq_size, + static int create_qp(struct rtrs_con *con, struct ib_pd *pd, + u32 max_send_wr, u32 max_recv_wr, u32 max_sge) + { +- struct ib_qp_init_attr init_attr = {NULL}; ++ struct ib_qp_init_attr init_attr = {}; + struct rdma_cm_id *cm_id = con->cm_id; + int ret; + +-- +2.43.0 + diff --git a/queue-5.10/s390-smp-mcck-fix-early-ipi-handling.patch b/queue-5.10/s390-smp-mcck-fix-early-ipi-handling.patch new file mode 100644 index 00000000000..0c5c1595a0c --- /dev/null +++ b/queue-5.10/s390-smp-mcck-fix-early-ipi-handling.patch @@ -0,0 +1,84 @@ +From 61aaa2311cd707d6f970cb9c58b81a8c7d911076 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Sep 2023 15:49:37 +0200 +Subject: s390/smp,mcck: fix early IPI handling + +From: Heiko Carstens + +[ Upstream commit 4a1725281fc5b0009944b1c0e1d2c1dc311a09ec ] + +Both the external call as well as the emergency signal submask bits in +control register 0 are set before any interrupt handler is registered. + +Change the order and first register the interrupt handler and only then +enable the interrupts by setting the corresponding bits in control +register 0. + +This prevents that the second part of the machine check handler for +early machine check handling is not executed: the machine check handler +sends an IPI to the CPU it runs on. If the corresponding interrupts are +enabled, but no interrupt handler is present, the interrupt is ignored. + +Reviewed-by: Sven Schnelle +Acked-by: Alexander Gordeev +Signed-off-by: Heiko Carstens +Signed-off-by: Vasily Gorbik +Signed-off-by: Sasha Levin +--- + arch/s390/kernel/early.c | 12 +++--------- + arch/s390/kernel/smp.c | 4 ++-- + 2 files changed, 5 insertions(+), 11 deletions(-) + +diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c +index 985e1e7553336..bac1be43d36cb 100644 +--- a/arch/s390/kernel/early.c ++++ b/arch/s390/kernel/early.c +@@ -252,15 +252,9 @@ static inline void save_vector_registers(void) + #endif + } + +-static inline void setup_control_registers(void) ++static inline void setup_low_address_protection(void) + { +- unsigned long reg; +- +- __ctl_store(reg, 0, 0); +- reg |= CR0_LOW_ADDRESS_PROTECTION; +- reg |= CR0_EMERGENCY_SIGNAL_SUBMASK; +- reg |= CR0_EXTERNAL_CALL_SUBMASK; +- __ctl_load(reg, 0, 0); ++ __ctl_set_bit(0, 28); + } + + static inline void setup_access_registers(void) +@@ -313,7 +307,7 @@ void __init startup_init(void) + save_vector_registers(); + setup_topology(); + sclp_early_detect(); +- setup_control_registers(); ++ setup_low_address_protection(); + setup_access_registers(); + lockdep_on(); + } +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 5674792726cd9..2e0c3b0a5a58a 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -982,12 +982,12 @@ void __init smp_fill_possible_mask(void) + + void __init smp_prepare_cpus(unsigned int max_cpus) + { +- /* request the 0x1201 emergency signal external interrupt */ + if (register_external_irq(EXT_IRQ_EMERGENCY_SIG, do_ext_call_interrupt)) + panic("Couldn't request external interrupt 0x1201"); +- /* request the 0x1202 external call external interrupt */ ++ ctl_set_bit(0, 14); + if (register_external_irq(EXT_IRQ_EXTERNAL_CALL, do_ext_call_interrupt)) + panic("Couldn't request external interrupt 0x1202"); ++ ctl_set_bit(0, 13); + } + + void __init smp_prepare_boot_cpu(void) +-- +2.43.0 + diff --git a/queue-5.10/scsi-spi-fix-sshdr-use.patch b/queue-5.10/scsi-spi-fix-sshdr-use.patch new file mode 100644 index 00000000000..1d48c64b6f8 --- /dev/null +++ b/queue-5.10/scsi-spi-fix-sshdr-use.patch @@ -0,0 +1,45 @@ +From 0a38273f0c8977a5b2a287117658789eb57c746e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 16:00:07 -0500 +Subject: scsi: spi: Fix sshdr use + +From: Mike Christie + +[ Upstream commit 0b149cee836aa53989ea089af1cb9d90d7c6ac9e ] + +If scsi_execute_cmd returns < 0, it doesn't initialize the sshdr, so we +shouldn't access the sshdr. If it returns 0, then the cmd executed +successfully, so there is no need to check the sshdr. This has us access +the sshdr when we get a return value > 0. + +Signed-off-by: Mike Christie +Link: https://lore.kernel.org/r/20231004210013.5601-7-michael.christie@oracle.com +Reviewed-by: Christoph Hellwig +Reviewed-by: John Garry +Reviewed-by: Martin Wilck +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/scsi_transport_spi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c +index c37dd15d16d24..83f2576ed2aa0 100644 +--- a/drivers/scsi/scsi_transport_spi.c ++++ b/drivers/scsi/scsi_transport_spi.c +@@ -677,10 +677,10 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer, + for (r = 0; r < retries; r++) { + result = spi_execute(sdev, spi_write_buffer, DMA_TO_DEVICE, + buffer, len, &sshdr); +- if(result || !scsi_device_online(sdev)) { ++ if (result || !scsi_device_online(sdev)) { + + scsi_device_set_state(sdev, SDEV_QUIESCE); +- if (scsi_sense_valid(&sshdr) ++ if (result > 0 && scsi_sense_valid(&sshdr) + && sshdr.sense_key == ILLEGAL_REQUEST + /* INVALID FIELD IN CDB */ + && sshdr.asc == 0x24 && sshdr.ascq == 0x00) +-- +2.43.0 + diff --git a/queue-5.10/series b/queue-5.10/series index 141f6cfff3b..482eaed9ff4 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -30,3 +30,19 @@ netfilter-flowtable-initialise-extack-before-use.patch net-hns3-fix-wrong-use-of-semaphore-up.patch net-hns3-fix-a-deadlock-problem-when-config-tc-durin.patch alsa-hda-realtek-fix-noise-from-speakers-on-lenovo-i.patch +ssb-fix-division-by-zero-issue-in-ssb_calc_clock_rat.patch +wifi-mac80211-fix-ba-session-teardown-race.patch +wifi-cw1200-avoid-processing-an-invalid-tim-ie.patch +i2c-riic-avoid-potential-division-by-zero.patch +rdma-rtrs-fix-the-problem-of-variable-not-initialize.patch +s390-smp-mcck-fix-early-ipi-handling.patch +media-radio-isa-use-dev_name-to-fill-in-bus_info.patch +staging-iio-resolver-ad2s1210-fix-use-before-initial.patch +drm-amd-display-validate-hw_points_num-before-using-.patch +staging-ks7010-disable-bh-on-tx_dev_lock.patch +binfmt_misc-cleanup-on-filesystem-umount.patch +media-qcom-venus-fix-incorrect-return-value.patch +scsi-spi-fix-sshdr-use.patch +gfs2-setattr_chown-add-missing-initialization.patch +wifi-iwlwifi-abort-scan-when-rfkill-on-but-device-en.patch +ib-hfi1-fix-potential-deadlock-on-irq_src_lock-and-d.patch diff --git a/queue-5.10/ssb-fix-division-by-zero-issue-in-ssb_calc_clock_rat.patch b/queue-5.10/ssb-fix-division-by-zero-issue-in-ssb_calc_clock_rat.patch new file mode 100644 index 00000000000..1e6ec5a361d --- /dev/null +++ b/queue-5.10/ssb-fix-division-by-zero-issue-in-ssb_calc_clock_rat.patch @@ -0,0 +1,49 @@ +From 7516e6ec51f1fdc6ac6377a9827f3f2c8eef9c3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Sep 2023 02:23:46 +0300 +Subject: ssb: Fix division by zero issue in ssb_calc_clock_rate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rand Deeb + +[ Upstream commit e0b5127fa134fe0284d58877b6b3133939c8b3ce ] + +In ssb_calc_clock_rate(), there is a potential issue where the value of +m1 could be zero due to initialization using clkfactor_f6_resolv(). This +situation raised concerns about the possibility of a division by zero +error. + +We fixed it by following the suggestions provided by Larry Finger + and Michael Büsch . The fix +involves returning a value of 1 instead of 0 in clkfactor_f6_resolv(). +This modification ensures the proper functioning of the code and +eliminates the risk of division by zero errors. + +Signed-off-by: Rand Deeb +Acked-by: Larry Finger +Acked-by: Michael Büsch +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230904232346.34991-1-rand.sec96@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/ssb/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c +index 0a26984acb2ca..9e54bc7eec663 100644 +--- a/drivers/ssb/main.c ++++ b/drivers/ssb/main.c +@@ -835,7 +835,7 @@ static u32 clkfactor_f6_resolve(u32 v) + case SSB_CHIPCO_CLK_F6_7: + return 7; + } +- return 0; ++ return 1; + } + + /* Calculate the speed the backplane would run at a given set of clockcontrol values */ +-- +2.43.0 + diff --git a/queue-5.10/staging-iio-resolver-ad2s1210-fix-use-before-initial.patch b/queue-5.10/staging-iio-resolver-ad2s1210-fix-use-before-initial.patch new file mode 100644 index 00000000000..fea59ac6399 --- /dev/null +++ b/queue-5.10/staging-iio-resolver-ad2s1210-fix-use-before-initial.patch @@ -0,0 +1,49 @@ +From 47e4dc6e9d6d5647289f7e2cf9bcaf15336c82ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 12:23:07 -0500 +Subject: staging: iio: resolver: ad2s1210: fix use before initialization + +From: David Lechner + +[ Upstream commit 7fe2d05cee46b1c4d9f1efaeab08cc31a0dfff60 ] + +This fixes a use before initialization in ad2s1210_probe(). The +ad2s1210_setup_gpios() function uses st->sdev but it was being called +before this field was initialized. + +Signed-off-by: David Lechner +Link: https://lore.kernel.org/r/20230929-ad2s1210-mainline-v3-2-fa4364281745@baylibre.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/staging/iio/resolver/ad2s1210.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c +index a19cfb2998c93..f19bb5c796cf7 100644 +--- a/drivers/staging/iio/resolver/ad2s1210.c ++++ b/drivers/staging/iio/resolver/ad2s1210.c +@@ -658,9 +658,6 @@ static int ad2s1210_probe(struct spi_device *spi) + if (!indio_dev) + return -ENOMEM; + st = iio_priv(indio_dev); +- ret = ad2s1210_setup_gpios(st); +- if (ret < 0) +- return ret; + + spi_set_drvdata(spi, indio_dev); + +@@ -671,6 +668,10 @@ static int ad2s1210_probe(struct spi_device *spi) + st->resolution = 12; + st->fexcit = AD2S1210_DEF_EXCIT; + ++ ret = ad2s1210_setup_gpios(st); ++ if (ret < 0) ++ return ret; ++ + indio_dev->info = &ad2s1210_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad2s1210_channels; +-- +2.43.0 + diff --git a/queue-5.10/staging-ks7010-disable-bh-on-tx_dev_lock.patch b/queue-5.10/staging-ks7010-disable-bh-on-tx_dev_lock.patch new file mode 100644 index 00000000000..09fe50f7d13 --- /dev/null +++ b/queue-5.10/staging-ks7010-disable-bh-on-tx_dev_lock.patch @@ -0,0 +1,51 @@ +From f7d4e0263eda3ce14218c4e7afc5e7d2a2792974 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 16:13:23 +0000 +Subject: staging: ks7010: disable bh on tx_dev_lock + +From: Chengfeng Ye + +[ Upstream commit 058cbee52ccd7be77e373d31a4f14670cfd32018 ] + +As &priv->tx_dev.tx_dev_lock is also acquired by xmit callback which +could be call from timer under softirq context, use spin_lock_bh() +on it to prevent potential deadlock. + +hostif_sme_work() +--> hostif_sme_set_pmksa() +--> hostif_mib_set_request() +--> ks_wlan_hw_tx() +--> spin_lock(&priv->tx_dev.tx_dev_lock) + +ks_wlan_start_xmit() +--> hostif_data_request() +--> ks_wlan_hw_tx() +--> spin_lock(&priv->tx_dev.tx_dev_lock) + +Signed-off-by: Chengfeng Ye +Link: https://lore.kernel.org/r/20230926161323.41928-1-dg573847474@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/ks7010/ks7010_sdio.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c +index 8c740c771f509..8e3fc4b78fd20 100644 +--- a/drivers/staging/ks7010/ks7010_sdio.c ++++ b/drivers/staging/ks7010/ks7010_sdio.c +@@ -395,9 +395,9 @@ int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p, unsigned long size, + priv->hostt.buff[priv->hostt.qtail] = le16_to_cpu(hdr->event); + priv->hostt.qtail = (priv->hostt.qtail + 1) % SME_EVENT_BUFF_SIZE; + +- spin_lock(&priv->tx_dev.tx_dev_lock); ++ spin_lock_bh(&priv->tx_dev.tx_dev_lock); + result = enqueue_txdev(priv, p, size, complete_handler, skb); +- spin_unlock(&priv->tx_dev.tx_dev_lock); ++ spin_unlock_bh(&priv->tx_dev.tx_dev_lock); + + if (txq_has_space(priv)) + queue_delayed_work(priv->wq, &priv->rw_dwork, 0); +-- +2.43.0 + diff --git a/queue-5.10/wifi-cw1200-avoid-processing-an-invalid-tim-ie.patch b/queue-5.10/wifi-cw1200-avoid-processing-an-invalid-tim-ie.patch new file mode 100644 index 00000000000..26ec264622d --- /dev/null +++ b/queue-5.10/wifi-cw1200-avoid-processing-an-invalid-tim-ie.patch @@ -0,0 +1,39 @@ +From f2b24523c328e1cddf9f490cf83d1bcb97a44d1e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Aug 2023 11:22:57 -0700 +Subject: wifi: cw1200: Avoid processing an invalid TIM IE + +From: Jeff Johnson + +[ Upstream commit b7bcea9c27b3d87b54075735c870500123582145 ] + +While converting struct ieee80211_tim_ie::virtual_map to be a flexible +array it was observed that the TIM IE processing in cw1200_rx_cb() +could potentially process a malformed IE in a manner that could result +in a buffer over-read. Add logic to verify that the TIM IE length is +large enough to hold a valid TIM payload before processing it. + +Signed-off-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230831-ieee80211_tim_ie-v3-1-e10ff584ab5d@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/st/cw1200/txrx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/st/cw1200/txrx.c b/drivers/net/wireless/st/cw1200/txrx.c +index 400dd585916b5..7ef0886503578 100644 +--- a/drivers/net/wireless/st/cw1200/txrx.c ++++ b/drivers/net/wireless/st/cw1200/txrx.c +@@ -1170,7 +1170,7 @@ void cw1200_rx_cb(struct cw1200_common *priv, + size_t ies_len = skb->len - (ies - (u8 *)(skb->data)); + + tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len); +- if (tim_ie) { ++ if (tim_ie && tim_ie[1] >= sizeof(struct ieee80211_tim_ie)) { + struct ieee80211_tim_ie *tim = + (struct ieee80211_tim_ie *)&tim_ie[2]; + +-- +2.43.0 + diff --git a/queue-5.10/wifi-iwlwifi-abort-scan-when-rfkill-on-but-device-en.patch b/queue-5.10/wifi-iwlwifi-abort-scan-when-rfkill-on-but-device-en.patch new file mode 100644 index 00000000000..5e8f2667e11 --- /dev/null +++ b/queue-5.10/wifi-iwlwifi-abort-scan-when-rfkill-on-but-device-en.patch @@ -0,0 +1,47 @@ +From 8804021e45561e7ec894b9932436393daf981ee1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 12:36:28 +0300 +Subject: wifi: iwlwifi: abort scan when rfkill on but device enabled + +From: Miri Korenblit + +[ Upstream commit 3c6a0b1f0add72e7f522bc9145222b86d0a7712a ] + +In RFKILL we first set the RFKILL bit, then we abort scan +(if one exists) by waiting for the notification from FW +and notifying mac80211. And then we stop the device. +But in case we have a scan ongoing in the period of time between +rfkill on and before the device is stopped - we will not wait for the +FW notification because of the iwl_mvm_is_radio_killed() condition, +and then the scan_status and uid_status are misconfigured, +(scan_status is cleared but uid_status not) +and when the notification suddenly arrives (before stopping the device) +we will get into the assert about scan_status and uid_status mismatch. +Fix this by waiting for FW notif when rfkill is on but the device isn't +disabled yet. + +Signed-off-by: Miri Korenblit +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20231004123422.c43b69aa2c77.Icc7b5efb47974d6f499156ff7510b786e177993b@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +index a9df48c75155b..a52af491eed58 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +@@ -2675,7 +2675,7 @@ int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify) + if (!(mvm->scan_status & type)) + return 0; + +- if (iwl_mvm_is_radio_killed(mvm)) { ++ if (!test_bit(STATUS_DEVICE_ENABLED, &mvm->trans->status)) { + ret = 0; + goto out; + } +-- +2.43.0 + diff --git a/queue-5.10/wifi-mac80211-fix-ba-session-teardown-race.patch b/queue-5.10/wifi-mac80211-fix-ba-session-teardown-race.patch new file mode 100644 index 00000000000..90bda1f44b6 --- /dev/null +++ b/queue-5.10/wifi-mac80211-fix-ba-session-teardown-race.patch @@ -0,0 +1,113 @@ +From 01788f42547f4d4f2c79fa229b4df7f35890b61c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 20:16:11 +0200 +Subject: wifi: mac80211: fix BA session teardown race + +From: Johannes Berg + +[ Upstream commit 05f136220d17839eb7c155f015ace9152f603225 ] + +As previously reported by Alexander, whose commit 69403bad97aa +("wifi: mac80211: sdata can be NULL during AMPDU start") I'm +reverting as part of this commit, there's a race between station +destruction and aggregation setup, where the aggregation setup +can happen while the station is being removed and queue the work +after ieee80211_sta_tear_down_BA_sessions() has already run in +__sta_info_destroy_part1(), and thus the worker will run with a +now freed station. In his case, this manifested in a NULL sdata +pointer, but really there's no guarantee whatsoever. + +The real issue seems to be that it's possible at all to have a +situation where this occurs - we want to stop the BA sessions +when doing _part1, but we cannot be sure, and WLAN_STA_BLOCK_BA +isn't necessarily effective since we don't know that the setup +isn't concurrently running and already got past the check. + +Simply call ieee80211_sta_tear_down_BA_sessions() again in the +second part of station destruction, since at that point really +nothing else can hold a reference to the station any more. + +Also revert the sdata checks since those are just misleading at +this point. + +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/agg-tx.c | 6 +----- + net/mac80211/driver-ops.c | 3 --- + net/mac80211/sta_info.c | 14 ++++++++++++++ + 3 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c +index 92e5812daf892..4b4ab1961068f 100644 +--- a/net/mac80211/agg-tx.c ++++ b/net/mac80211/agg-tx.c +@@ -491,7 +491,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) + { + struct tid_ampdu_tx *tid_tx; + struct ieee80211_local *local = sta->local; +- struct ieee80211_sub_if_data *sdata; ++ struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ieee80211_ampdu_params params = { + .sta = &sta->sta, + .action = IEEE80211_AMPDU_TX_START, +@@ -521,7 +521,6 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) + */ + synchronize_net(); + +- sdata = sta->sdata; + params.ssn = sta->tid_seq[tid] >> 4; + ret = drv_ampdu_action(local, sdata, ¶ms); + tid_tx->ssn = params.ssn; +@@ -535,9 +534,6 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) + */ + set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state); + } else if (ret) { +- if (!sdata) +- return; +- + ht_dbg(sdata, + "BA request denied - HW unavailable for %pM tid %d\n", + sta->sta.addr, tid); +diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c +index 120bd9cdf7dfa..48322e45e7ddb 100644 +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -331,9 +331,6 @@ int drv_ampdu_action(struct ieee80211_local *local, + + might_sleep(); + +- if (!sdata) +- return -EIO; +- + sdata = get_bss_sdata(sdata); + if (!check_sdata_in_driver(sdata)) + return -EIO; +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index f7637176d719d..3bb7a3314788e 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -1064,6 +1064,20 @@ static void __sta_info_destroy_part2(struct sta_info *sta) + * after _part1 and before _part2! + */ + ++ /* ++ * There's a potential race in _part1 where we set WLAN_STA_BLOCK_BA ++ * but someone might have just gotten past a check, and not yet into ++ * queuing the work/creating the data/etc. ++ * ++ * Do another round of destruction so that the worker is certainly ++ * canceled before we later free the station. ++ * ++ * Since this is after synchronize_rcu()/synchronize_net() we're now ++ * certain that nobody can actually hold a reference to the STA and ++ * be calling e.g. ieee80211_start_tx_ba_session(). ++ */ ++ ieee80211_sta_tear_down_BA_sessions(sta, AGG_STOP_DESTROY_STA); ++ + might_sleep(); + lockdep_assert_held(&local->sta_mtx); + +-- +2.43.0 +