]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Tue, 14 Mar 2023 02:17:12 +0000 (22:17 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 14 Mar 2023 02:17:12 +0000 (22:17 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
23 files changed:
queue-5.15/attr-add-in_group_or_capable.patch [new file with mode: 0644]
queue-5.15/attr-add-setattr_should_drop_sgid.patch [new file with mode: 0644]
queue-5.15/attr-use-consistent-sgid-stripping-checks.patch [new file with mode: 0644]
queue-5.15/fs-add-mode_strip_sgid-helper.patch [new file with mode: 0644]
queue-5.15/fs-move-s_isgid-stripping-into-the-vfs_-helpers.patch [new file with mode: 0644]
queue-5.15/fs-move-should_remove_suid.patch [new file with mode: 0644]
queue-5.15/fs-use-consistent-setgid-checks-in-is_sxid.patch [new file with mode: 0644]
queue-5.15/iommu-amd-add-a-length-limitation-for-the-ivrs_acpih.patch [new file with mode: 0644]
queue-5.15/iommu-amd-add-pci-segment-support-for-ivrs_-ioapic-h.patch [new file with mode: 0644]
queue-5.15/iommu-amd-fix-ill-formed-ivrs_ioapic-ivrs_hpet-and-i.patch [new file with mode: 0644]
queue-5.15/irqdomain-fix-mapping-creation-race.patch [new file with mode: 0644]
queue-5.15/nbd-use-the-correct-block_device-in-nbd_bdev_reset.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/staging-rtl8723bs-clean-up-comparsions-to-null.patch [new file with mode: 0644]
queue-5.15/staging-rtl8723bs-fix-key-store-index-handling.patch [new file with mode: 0644]
queue-5.15/staging-rtl8723bs-fix-placement-of-braces.patch [new file with mode: 0644]
queue-5.15/staging-rtl8723bs-placing-opening-braces-in-previous.patch [new file with mode: 0644]
queue-5.15/tpm-eventlog-don-t-abort-tpm_read_log-on-faulty-acpi.patch [new file with mode: 0644]
queue-5.15/watch_queue-fix-ioc_watch_queue_set_size-alloc-error.patch [new file with mode: 0644]
queue-5.15/xfs-fallocate-should-call-file_modified.patch [new file with mode: 0644]
queue-5.15/xfs-remove-xfs_prealloc_sync.patch [new file with mode: 0644]
queue-5.15/xfs-set-prealloc-flag-in-xfs_alloc_file_space.patch [new file with mode: 0644]
queue-5.15/xfs-use-setattr_copy-to-set-vfs-inode-attributes.patch [new file with mode: 0644]

diff --git a/queue-5.15/attr-add-in_group_or_capable.patch b/queue-5.15/attr-add-in_group_or_capable.patch
new file mode 100644 (file)
index 0000000..2ceb29f
--- /dev/null
@@ -0,0 +1,125 @@
+From 8b129e70cf645e8e7f1a6a14e97db0068c8e6276 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:18 -0800
+Subject: attr: add in_group_or_capable()
+
+From: Christian Brauner <brauner@kernel.org>
+
+commit 11c2a8700cdcabf9b639b7204a1e38e2a0b6798e upstream.
+
+[backport to 5.15.y, prior to vfsgid_t]
+
+In setattr_{copy,prepare}() we need to perform the same permission
+checks to determine whether we need to drop the setgid bit or not.
+Instead of open-coding it twice add a simple helper the encapsulates the
+logic. We will reuse this helpers to make dropping the setgid bit during
+write operations more consistent in a follow up patch.
+
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/attr.c     |  8 ++++----
+ fs/inode.c    | 28 ++++++++++++++++++++++++----
+ fs/internal.h |  2 ++
+ 3 files changed, 30 insertions(+), 8 deletions(-)
+
+diff --git a/fs/attr.c b/fs/attr.c
+index f581c4d008971..686840aa91c8b 100644
+--- a/fs/attr.c
++++ b/fs/attr.c
+@@ -18,6 +18,8 @@
+ #include <linux/evm.h>
+ #include <linux/ima.h>
++#include "internal.h"
++
+ /**
+  * chown_ok - verify permissions to chown inode
+  * @mnt_userns:       user namespace of the mount @inode was found from
+@@ -141,8 +143,7 @@ int setattr_prepare(struct user_namespace *mnt_userns, struct dentry *dentry,
+                       mapped_gid = i_gid_into_mnt(mnt_userns, inode);
+               /* Also check the setgid bit! */
+-              if (!in_group_p(mapped_gid) &&
+-                  !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
++              if (!in_group_or_capable(mnt_userns, inode, mapped_gid))
+                       attr->ia_mode &= ~S_ISGID;
+       }
+@@ -257,8 +258,7 @@ void setattr_copy(struct user_namespace *mnt_userns, struct inode *inode,
+       if (ia_valid & ATTR_MODE) {
+               umode_t mode = attr->ia_mode;
+               kgid_t kgid = i_gid_into_mnt(mnt_userns, inode);
+-              if (!in_group_p(kgid) &&
+-                  !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
++              if (!in_group_or_capable(mnt_userns, inode, kgid))
+                       mode &= ~S_ISGID;
+               inode->i_mode = mode;
+       }
+diff --git a/fs/inode.c b/fs/inode.c
+index 957b2d18ec29f..a71fb82279bb1 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -2321,6 +2321,28 @@ struct timespec64 current_time(struct inode *inode)
+ }
+ EXPORT_SYMBOL(current_time);
++/**
++ * in_group_or_capable - check whether caller is CAP_FSETID privileged
++ * @mnt_userns: user namespace of the mount @inode was found from
++ * @inode:    inode to check
++ * @gid:      the new/current gid of @inode
++ *
++ * Check wether @gid is in the caller's group list or if the caller is
++ * privileged with CAP_FSETID over @inode. This can be used to determine
++ * whether the setgid bit can be kept or must be dropped.
++ *
++ * Return: true if the caller is sufficiently privileged, false if not.
++ */
++bool in_group_or_capable(struct user_namespace *mnt_userns,
++                       const struct inode *inode, kgid_t gid)
++{
++      if (in_group_p(gid))
++              return true;
++      if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
++              return true;
++      return false;
++}
++
+ /**
+  * mode_strip_sgid - handle the sgid bit for non-directories
+  * @mnt_userns: User namespace of the mount the inode was created from
+@@ -2342,11 +2364,9 @@ umode_t mode_strip_sgid(struct user_namespace *mnt_userns,
+               return mode;
+       if (S_ISDIR(mode) || !dir || !(dir->i_mode & S_ISGID))
+               return mode;
+-      if (in_group_p(i_gid_into_mnt(mnt_userns, dir)))
+-              return mode;
+-      if (capable_wrt_inode_uidgid(mnt_userns, dir, CAP_FSETID))
++      if (in_group_or_capable(mnt_userns, dir,
++                              i_gid_into_mnt(mnt_userns, dir)))
+               return mode;
+-
+       return mode & ~S_ISGID;
+ }
+ EXPORT_SYMBOL(mode_strip_sgid);
+diff --git a/fs/internal.h b/fs/internal.h
+index 9075490f21a62..c898147272817 100644
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -150,6 +150,8 @@ extern int vfs_open(const struct path *, struct file *);
+ extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc);
+ extern void inode_add_lru(struct inode *inode);
+ extern int dentry_needs_remove_privs(struct dentry *dentry);
++bool in_group_or_capable(struct user_namespace *mnt_userns,
++                       const struct inode *inode, kgid_t gid);
+ /*
+  * fs-writeback.c
+-- 
+2.39.2
+
diff --git a/queue-5.15/attr-add-setattr_should_drop_sgid.patch b/queue-5.15/attr-add-setattr_should_drop_sgid.patch
new file mode 100644 (file)
index 0000000..aa118a8
--- /dev/null
@@ -0,0 +1,89 @@
+From fdba6071d3b7bd547ea334d8b9a69ccf07bfbfcd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:20 -0800
+Subject: attr: add setattr_should_drop_sgid()
+
+From: Christian Brauner <brauner@kernel.org>
+
+commit 72ae017c5451860443a16fb2a8c243bff3e396b8 upstream.
+
+[backport to 5.15.y, prior to vfsgid_t]
+
+The current setgid stripping logic during write and ownership change
+operations is inconsistent and strewn over multiple places. In order to
+consolidate it and make more consistent we'll add a new helper
+setattr_should_drop_sgid(). The function retains the old behavior where
+we remove the S_ISGID bit unconditionally when S_IXGRP is set but also
+when it isn't set and the caller is neither in the group of the inode
+nor privileged over the inode.
+
+We will use this helper both in write operation permission removal such
+as file_remove_privs() as well as in ownership change operations.
+
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/attr.c     | 28 ++++++++++++++++++++++++++++
+ fs/internal.h |  6 ++++++
+ 2 files changed, 34 insertions(+)
+
+diff --git a/fs/attr.c b/fs/attr.c
+index f045431bab1ad..965be68ed8fa0 100644
+--- a/fs/attr.c
++++ b/fs/attr.c
+@@ -20,6 +20,34 @@
+ #include "internal.h"
++/**
++ * setattr_should_drop_sgid - determine whether the setgid bit needs to be
++ *                            removed
++ * @mnt_userns:       user namespace of the mount @inode was found from
++ * @inode:    inode to check
++ *
++ * This function determines whether the setgid bit needs to be removed.
++ * We retain backwards compatibility and require setgid bit to be removed
++ * unconditionally if S_IXGRP is set. Otherwise we have the exact same
++ * requirements as setattr_prepare() and setattr_copy().
++ *
++ * Return: ATTR_KILL_SGID if setgid bit needs to be removed, 0 otherwise.
++ */
++int setattr_should_drop_sgid(struct user_namespace *mnt_userns,
++                           const struct inode *inode)
++{
++      umode_t mode = inode->i_mode;
++
++      if (!(mode & S_ISGID))
++              return 0;
++      if (mode & S_IXGRP)
++              return ATTR_KILL_SGID;
++      if (!in_group_or_capable(mnt_userns, inode,
++                               i_gid_into_mnt(mnt_userns, inode)))
++              return ATTR_KILL_SGID;
++      return 0;
++}
++
+ /*
+  * The logic we want is
+  *
+diff --git a/fs/internal.h b/fs/internal.h
+index c898147272817..45cf31d7380b8 100644
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -231,3 +231,9 @@ struct xattr_ctx {
+ int setxattr_copy(const char __user *name, struct xattr_ctx *ctx);
+ int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
+               struct xattr_ctx *ctx);
++
++/*
++ * fs/attr.c
++ */
++int setattr_should_drop_sgid(struct user_namespace *mnt_userns,
++                           const struct inode *inode);
+-- 
+2.39.2
+
diff --git a/queue-5.15/attr-use-consistent-sgid-stripping-checks.patch b/queue-5.15/attr-use-consistent-sgid-stripping-checks.patch
new file mode 100644 (file)
index 0000000..4a0f0b1
--- /dev/null
@@ -0,0 +1,350 @@
+From fb111ba84f9782fa9d00fe857c578321fdf60658 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:21 -0800
+Subject: attr: use consistent sgid stripping checks
+
+From: Christian Brauner <brauner@kernel.org>
+
+commit ed5a7047d2011cb6b2bf84ceb6680124cc6a7d95 upstream.
+
+[backport to 5.15.y, prior to vfsgid_t]
+
+Currently setgid stripping in file_remove_privs()'s should_remove_suid()
+helper is inconsistent with other parts of the vfs. Specifically, it only
+raises ATTR_KILL_SGID if the inode is S_ISGID and S_IXGRP but not if the
+inode isn't in the caller's groups and the caller isn't privileged over the
+inode although we require this already in setattr_prepare() and
+setattr_copy() and so all filesystem implement this requirement implicitly
+because they have to use setattr_{prepare,copy}() anyway.
+
+But the inconsistency shows up in setgid stripping bugs for overlayfs in
+xfstests (e.g., generic/673, generic/683, generic/685, generic/686,
+generic/687). For example, we test whether suid and setgid stripping works
+correctly when performing various write-like operations as an unprivileged
+user (fallocate, reflink, write, etc.):
+
+echo "Test 1 - qa_user, non-exec file $verb"
+setup_testfile
+chmod a+rws $junk_file
+commit_and_check "$qa_user" "$verb" 64k 64k
+
+The test basically creates a file with 6666 permissions. While the file has
+the S_ISUID and S_ISGID bits set it does not have the S_IXGRP set. On a
+regular filesystem like xfs what will happen is:
+
+sys_fallocate()
+-> vfs_fallocate()
+   -> xfs_file_fallocate()
+      -> file_modified()
+         -> __file_remove_privs()
+            -> dentry_needs_remove_privs()
+               -> should_remove_suid()
+            -> __remove_privs()
+               newattrs.ia_valid = ATTR_FORCE | kill;
+               -> notify_change()
+                  -> setattr_copy()
+
+In should_remove_suid() we can see that ATTR_KILL_SUID is raised
+unconditionally because the file in the test has S_ISUID set.
+
+But we also see that ATTR_KILL_SGID won't be set because while the file
+is S_ISGID it is not S_IXGRP (see above) which is a condition for
+ATTR_KILL_SGID being raised.
+
+So by the time we call notify_change() we have attr->ia_valid set to
+ATTR_KILL_SUID | ATTR_FORCE. Now notify_change() sees that
+ATTR_KILL_SUID is set and does:
+
+ia_valid = attr->ia_valid |= ATTR_MODE
+attr->ia_mode = (inode->i_mode & ~S_ISUID);
+
+which means that when we call setattr_copy() later we will definitely
+update inode->i_mode. Note that attr->ia_mode still contains S_ISGID.
+
+Now we call into the filesystem's ->setattr() inode operation which will
+end up calling setattr_copy(). Since ATTR_MODE is set we will hit:
+
+if (ia_valid & ATTR_MODE) {
+        umode_t mode = attr->ia_mode;
+        vfsgid_t vfsgid = i_gid_into_vfsgid(mnt_userns, inode);
+        if (!vfsgid_in_group_p(vfsgid) &&
+            !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
+                mode &= ~S_ISGID;
+        inode->i_mode = mode;
+}
+
+and since the caller in the test is neither capable nor in the group of the
+inode the S_ISGID bit is stripped.
+
+But assume the file isn't suid then ATTR_KILL_SUID won't be raised which
+has the consequence that neither the setgid nor the suid bits are stripped
+even though it should be stripped because the inode isn't in the caller's
+groups and the caller isn't privileged over the inode.
+
+If overlayfs is in the mix things become a bit more complicated and the bug
+shows up more clearly. When e.g., ovl_setattr() is hit from
+ovl_fallocate()'s call to file_remove_privs() then ATTR_KILL_SUID and
+ATTR_KILL_SGID might be raised but because the check in notify_change() is
+questioning the ATTR_KILL_SGID flag again by requiring S_IXGRP for it to be
+stripped the S_ISGID bit isn't removed even though it should be stripped:
+
+sys_fallocate()
+-> vfs_fallocate()
+   -> ovl_fallocate()
+      -> file_remove_privs()
+         -> dentry_needs_remove_privs()
+            -> should_remove_suid()
+         -> __remove_privs()
+            newattrs.ia_valid = ATTR_FORCE | kill;
+            -> notify_change()
+               -> ovl_setattr()
+                  // TAKE ON MOUNTER'S CREDS
+                  -> ovl_do_notify_change()
+                     -> notify_change()
+                  // GIVE UP MOUNTER'S CREDS
+     // TAKE ON MOUNTER'S CREDS
+     -> vfs_fallocate()
+        -> xfs_file_fallocate()
+           -> file_modified()
+              -> __file_remove_privs()
+                 -> dentry_needs_remove_privs()
+                    -> should_remove_suid()
+                 -> __remove_privs()
+                    newattrs.ia_valid = attr_force | kill;
+                    -> notify_change()
+
+The fix for all of this is to make file_remove_privs()'s
+should_remove_suid() helper to perform the same checks as we already
+require in setattr_prepare() and setattr_copy() and have notify_change()
+not pointlessly requiring S_IXGRP again. It doesn't make any sense in the
+first place because the caller must calculate the flags via
+should_remove_suid() anyway which would raise ATTR_KILL_SGID.
+
+While we're at it we move should_remove_suid() from inode.c to attr.c
+where it belongs with the rest of the iattr helpers. Especially since it
+returns ATTR_KILL_S{G,U}ID flags. We also rename it to
+setattr_should_drop_suidgid() to better reflect that it indicates both
+setuid and setgid bit removal and also that it returns attr flags.
+
+Running xfstests with this doesn't report any regressions. We should really
+try and use consistent checks.
+
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/trace/ftrace.rst |  2 +-
+ fs/attr.c                      | 33 +++++++++++++++++++--------------
+ fs/fuse/file.c                 |  2 +-
+ fs/inode.c                     |  7 ++++---
+ fs/internal.h                  |  2 +-
+ fs/ocfs2/file.c                |  4 ++--
+ fs/open.c                      |  8 ++++----
+ include/linux/fs.h             |  2 +-
+ 8 files changed, 33 insertions(+), 27 deletions(-)
+
+diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst
+index 4e5b26f03d5b1..d036946bce7ab 100644
+--- a/Documentation/trace/ftrace.rst
++++ b/Documentation/trace/ftrace.rst
+@@ -2929,7 +2929,7 @@ Produces::
+               bash-1994  [000] ....  4342.324898: ima_get_action <-process_measurement
+               bash-1994  [000] ....  4342.324898: ima_match_policy <-ima_get_action
+               bash-1994  [000] ....  4342.324899: do_truncate <-do_last
+-              bash-1994  [000] ....  4342.324899: should_remove_suid <-do_truncate
++              bash-1994  [000] ....  4342.324899: setattr_should_drop_suidgid <-do_truncate
+               bash-1994  [000] ....  4342.324899: notify_change <-do_truncate
+               bash-1994  [000] ....  4342.324900: current_fs_time <-notify_change
+               bash-1994  [000] ....  4342.324900: current_kernel_time <-current_fs_time
+diff --git a/fs/attr.c b/fs/attr.c
+index 965be68ed8fa0..0ca14cbd4b8bb 100644
+--- a/fs/attr.c
++++ b/fs/attr.c
+@@ -48,34 +48,39 @@ int setattr_should_drop_sgid(struct user_namespace *mnt_userns,
+       return 0;
+ }
+-/*
+- * The logic we want is
++/**
++ * setattr_should_drop_suidgid - determine whether the set{g,u}id bit needs to
++ *                               be dropped
++ * @mnt_userns:       user namespace of the mount @inode was found from
++ * @inode:    inode to check
+  *
+- *    if suid or (sgid and xgrp)
+- *            remove privs
++ * This function determines whether the set{g,u}id bits need to be removed.
++ * If the setuid bit needs to be removed ATTR_KILL_SUID is returned. If the
++ * setgid bit needs to be removed ATTR_KILL_SGID is returned. If both
++ * set{g,u}id bits need to be removed the corresponding mask of both flags is
++ * returned.
++ *
++ * Return: A mask of ATTR_KILL_S{G,U}ID indicating which - if any - setid bits
++ * to remove, 0 otherwise.
+  */
+-int should_remove_suid(struct dentry *dentry)
++int setattr_should_drop_suidgid(struct user_namespace *mnt_userns,
++                              struct inode *inode)
+ {
+-      umode_t mode = d_inode(dentry)->i_mode;
++      umode_t mode = inode->i_mode;
+       int kill = 0;
+       /* suid always must be killed */
+       if (unlikely(mode & S_ISUID))
+               kill = ATTR_KILL_SUID;
+-      /*
+-       * sgid without any exec bits is just a mandatory locking mark; leave
+-       * it alone.  If some exec bits are set, it's a real sgid; kill it.
+-       */
+-      if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
+-              kill |= ATTR_KILL_SGID;
++      kill |= setattr_should_drop_sgid(mnt_userns, inode);
+       if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
+               return kill;
+       return 0;
+ }
+-EXPORT_SYMBOL(should_remove_suid);
++EXPORT_SYMBOL(setattr_should_drop_suidgid);
+ /**
+  * chown_ok - verify permissions to chown inode
+@@ -440,7 +445,7 @@ int notify_change(struct user_namespace *mnt_userns, struct dentry *dentry,
+               }
+       }
+       if (ia_valid & ATTR_KILL_SGID) {
+-              if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
++              if (mode & S_ISGID) {
+                       if (!(ia_valid & ATTR_MODE)) {
+                               ia_valid = attr->ia_valid |= ATTR_MODE;
+                               attr->ia_mode = inode->i_mode;
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index cc95a1c376449..2b19d281351e5 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1295,7 +1295,7 @@ static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from)
+                       return err;
+               if (fc->handle_killpriv_v2 &&
+-                  should_remove_suid(file_dentry(file))) {
++                  setattr_should_drop_suidgid(&init_user_ns, file_inode(file))) {
+                       goto writethrough;
+               }
+diff --git a/fs/inode.c b/fs/inode.c
+index 3811269259e11..079b64f9b7561 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -1869,7 +1869,8 @@ EXPORT_SYMBOL(touch_atime);
+  * response to write or truncate. Return 0 if nothing has to be changed.
+  * Negative value on error (change should be denied).
+  */
+-int dentry_needs_remove_privs(struct dentry *dentry)
++int dentry_needs_remove_privs(struct user_namespace *mnt_userns,
++                            struct dentry *dentry)
+ {
+       struct inode *inode = d_inode(dentry);
+       int mask = 0;
+@@ -1878,7 +1879,7 @@ int dentry_needs_remove_privs(struct dentry *dentry)
+       if (IS_NOSEC(inode))
+               return 0;
+-      mask = should_remove_suid(dentry);
++      mask = setattr_should_drop_suidgid(mnt_userns, inode);
+       ret = security_inode_need_killpriv(dentry);
+       if (ret < 0)
+               return ret;
+@@ -1920,7 +1921,7 @@ int file_remove_privs(struct file *file)
+       if (IS_NOSEC(inode) || !S_ISREG(inode->i_mode))
+               return 0;
+-      kill = dentry_needs_remove_privs(dentry);
++      kill = dentry_needs_remove_privs(file_mnt_user_ns(file), dentry);
+       if (kill < 0)
+               return kill;
+       if (kill)
+diff --git a/fs/internal.h b/fs/internal.h
+index 45cf31d7380b8..46df4ce58e87e 100644
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -149,7 +149,7 @@ extern int vfs_open(const struct path *, struct file *);
+  */
+ extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc);
+ extern void inode_add_lru(struct inode *inode);
+-extern int dentry_needs_remove_privs(struct dentry *dentry);
++int dentry_needs_remove_privs(struct user_namespace *, struct dentry *dentry);
+ bool in_group_or_capable(struct user_namespace *mnt_userns,
+                        const struct inode *inode, kgid_t gid);
+diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
+index fc5f780fa2355..92182d4be247e 100644
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -1994,7 +1994,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
+               }
+       }
+-      if (file && should_remove_suid(file->f_path.dentry)) {
++      if (file && setattr_should_drop_suidgid(&init_user_ns, file_inode(file))) {
+               ret = __ocfs2_write_remove_suid(inode, di_bh);
+               if (ret) {
+                       mlog_errno(ret);
+@@ -2282,7 +2282,7 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
+                * inode. There's also the dinode i_size state which
+                * can be lost via setattr during extending writes (we
+                * set inode->i_size at the end of a write. */
+-              if (should_remove_suid(dentry)) {
++              if (setattr_should_drop_suidgid(&init_user_ns, inode)) {
+                       if (meta_level == 0) {
+                               ocfs2_inode_unlock_for_extent_tree(inode,
+                                                                  &di_bh,
+diff --git a/fs/open.c b/fs/open.c
+index 5e322f188e839..e93c33069055b 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -54,7 +54,7 @@ int do_truncate(struct user_namespace *mnt_userns, struct dentry *dentry,
+       }
+       /* Remove suid, sgid, and file capabilities on truncate too */
+-      ret = dentry_needs_remove_privs(dentry);
++      ret = dentry_needs_remove_privs(mnt_userns, dentry);
+       if (ret < 0)
+               return ret;
+       if (ret)
+@@ -671,10 +671,10 @@ int chown_common(const struct path *path, uid_t user, gid_t group)
+               newattrs.ia_valid |= ATTR_GID;
+               newattrs.ia_gid = gid;
+       }
+-      if (!S_ISDIR(inode->i_mode))
+-              newattrs.ia_valid |=
+-                      ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
+       inode_lock(inode);
++      if (!S_ISDIR(inode->i_mode))
++              newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV |
++                                   setattr_should_drop_sgid(mnt_userns, inode);
+       error = security_path_chown(path, uid, gid);
+       if (!error)
+               error = notify_change(mnt_userns, path->dentry, &newattrs,
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index be9be4a7216c7..9601c2d774c88 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -3133,7 +3133,7 @@ extern void __destroy_inode(struct inode *);
+ extern struct inode *new_inode_pseudo(struct super_block *sb);
+ extern struct inode *new_inode(struct super_block *sb);
+ extern void free_inode_nonrcu(struct inode *inode);
+-extern int should_remove_suid(struct dentry *);
++extern int setattr_should_drop_suidgid(struct user_namespace *, struct inode *);
+ extern int file_remove_privs(struct file *);
+ extern void __insert_inode_hash(struct inode *, unsigned long hashval);
+-- 
+2.39.2
+
diff --git a/queue-5.15/fs-add-mode_strip_sgid-helper.patch b/queue-5.15/fs-add-mode_strip_sgid-helper.patch
new file mode 100644 (file)
index 0000000..1a5fca8
--- /dev/null
@@ -0,0 +1,104 @@
+From 80a4bd6121353782815eb919865483ed4a7a414f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:16 -0800
+Subject: fs: add mode_strip_sgid() helper
+
+From: Yang Xu <xuyang2018.jy@fujitsu.com>
+
+commit 2b3416ceff5e6bd4922f6d1c61fb68113dd82302 upsream.
+
+Add a dedicated helper to handle the setgid bit when creating a new file
+in a setgid directory. This is a preparatory patch for moving setgid
+stripping into the vfs. The patch contains no functional changes.
+
+Currently the setgid stripping logic is open-coded directly in
+inode_init_owner() and the individual filesystems are responsible for
+handling setgid inheritance. Since this has proven to be brittle as
+evidenced by old issues we uncovered over the last months (see [1] to
+[3] below) we will try to move this logic into the vfs.
+
+Link: e014f37db1a2 ("xfs: use setattr_copy to set vfs inode attributes") [1]
+Link: 01ea173e103e ("xfs: fix up non-directory creation in SGID directories") [2]
+Link: fd84bfdddd16 ("ceph: fix up non-directory creation in SGID directories") [3]
+Link: https://lore.kernel.org/r/1657779088-2242-1-git-send-email-xuyang2018.jy@fujitsu.com
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Reviewed-and-Tested-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/inode.c         | 36 ++++++++++++++++++++++++++++++++----
+ include/linux/fs.h |  2 ++
+ 2 files changed, 34 insertions(+), 4 deletions(-)
+
+diff --git a/fs/inode.c b/fs/inode.c
+index 8279c700a2b7f..3740102c9bd5e 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -2165,10 +2165,8 @@ void inode_init_owner(struct user_namespace *mnt_userns, struct inode *inode,
+               /* Directories are special, and always inherit S_ISGID */
+               if (S_ISDIR(mode))
+                       mode |= S_ISGID;
+-              else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) &&
+-                       !in_group_p(i_gid_into_mnt(mnt_userns, dir)) &&
+-                       !capable_wrt_inode_uidgid(mnt_userns, dir, CAP_FSETID))
+-                      mode &= ~S_ISGID;
++              else
++                      mode = mode_strip_sgid(mnt_userns, dir, mode);
+       } else
+               inode_fsgid_set(inode, mnt_userns);
+       inode->i_mode = mode;
+@@ -2324,3 +2322,33 @@ struct timespec64 current_time(struct inode *inode)
+       return timestamp_truncate(now, inode);
+ }
+ EXPORT_SYMBOL(current_time);
++
++/**
++ * mode_strip_sgid - handle the sgid bit for non-directories
++ * @mnt_userns: User namespace of the mount the inode was created from
++ * @dir: parent directory inode
++ * @mode: mode of the file to be created in @dir
++ *
++ * If the @mode of the new file has both the S_ISGID and S_IXGRP bit
++ * raised and @dir has the S_ISGID bit raised ensure that the caller is
++ * either in the group of the parent directory or they have CAP_FSETID
++ * in their user namespace and are privileged over the parent directory.
++ * In all other cases, strip the S_ISGID bit from @mode.
++ *
++ * Return: the new mode to use for the file
++ */
++umode_t mode_strip_sgid(struct user_namespace *mnt_userns,
++                      const struct inode *dir, umode_t mode)
++{
++      if ((mode & (S_ISGID | S_IXGRP)) != (S_ISGID | S_IXGRP))
++              return mode;
++      if (S_ISDIR(mode) || !dir || !(dir->i_mode & S_ISGID))
++              return mode;
++      if (in_group_p(i_gid_into_mnt(mnt_userns, dir)))
++              return mode;
++      if (capable_wrt_inode_uidgid(mnt_userns, dir, CAP_FSETID))
++              return mode;
++
++      return mode & ~S_ISGID;
++}
++EXPORT_SYMBOL(mode_strip_sgid);
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 1e1ac116dd136..be9be4a7216c7 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1941,6 +1941,8 @@ extern long compat_ptr_ioctl(struct file *file, unsigned int cmd,
+ void inode_init_owner(struct user_namespace *mnt_userns, struct inode *inode,
+                     const struct inode *dir, umode_t mode);
+ extern bool may_open_dev(const struct path *path);
++umode_t mode_strip_sgid(struct user_namespace *mnt_userns,
++                      const struct inode *dir, umode_t mode);
+ /*
+  * This is the "filldir" function type, used by readdir() to let
+-- 
+2.39.2
+
diff --git a/queue-5.15/fs-move-s_isgid-stripping-into-the-vfs_-helpers.patch b/queue-5.15/fs-move-s_isgid-stripping-into-the-vfs_-helpers.patch
new file mode 100644 (file)
index 0000000..88631e3
--- /dev/null
@@ -0,0 +1,354 @@
+From 1f0af87a30c99969ad586ca55ba5c4c2b00f0dfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:17 -0800
+Subject: fs: move S_ISGID stripping into the vfs_*() helpers
+
+From: Yang Xu <xuyang2018.jy@fujitsu.com>
+
+commit 1639a49ccdce58ea248841ed9b23babcce6dbb0b upsream.
+
+Move setgid handling out of individual filesystems and into the VFS
+itself to stop the proliferation of setgid inheritance bugs.
+
+Creating files that have both the S_IXGRP and S_ISGID bit raised in
+directories that themselves have the S_ISGID bit set requires additional
+privileges to avoid security issues.
+
+When a filesystem creates a new inode it needs to take care that the
+caller is either in the group of the newly created inode or they have
+CAP_FSETID in their current user namespace and are privileged over the
+parent directory of the new inode. If any of these two conditions is
+true then the S_ISGID bit can be raised for an S_IXGRP file and if not
+it needs to be stripped.
+
+However, there are several key issues with the current implementation:
+
+* S_ISGID stripping logic is entangled with umask stripping.
+
+  If a filesystem doesn't support or enable POSIX ACLs then umask
+  stripping is done directly in the vfs before calling into the
+  filesystem.
+  If the filesystem does support POSIX ACLs then unmask stripping may be
+  done in the filesystem itself when calling posix_acl_create().
+
+  Since umask stripping has an effect on S_ISGID inheritance, e.g., by
+  stripping the S_IXGRP bit from the file to be created and all relevant
+  filesystems have to call posix_acl_create() before inode_init_owner()
+  where we currently take care of S_ISGID handling S_ISGID handling is
+  order dependent. IOW, whether or not you get a setgid bit depends on
+  POSIX ACLs and umask and in what order they are called.
+
+  Note that technically filesystems are free to impose their own
+  ordering between posix_acl_create() and inode_init_owner() meaning
+  that there's additional ordering issues that influence S_SIGID
+  inheritance.
+
+* Filesystems that don't rely on inode_init_owner() don't get S_ISGID
+  stripping logic.
+
+  While that may be intentional (e.g. network filesystems might just
+  defer setgid stripping to a server) it is often just a security issue.
+
+This is not just ugly it's unsustainably messy especially since we do
+still have bugs in this area years after the initial round of setgid
+bugfixes.
+
+So the current state is quite messy and while we won't be able to make
+it completely clean as posix_acl_create() is still a filesystem specific
+call we can improve the S_SIGD stripping situation quite a bit by
+hoisting it out of inode_init_owner() and into the vfs creation
+operations. This means we alleviate the burden for filesystems to handle
+S_ISGID stripping correctly and can standardize the ordering between
+S_ISGID and umask stripping in the vfs.
+
+We add a new helper vfs_prepare_mode() so S_ISGID handling is now done
+in the VFS before umask handling. This has S_ISGID handling is
+unaffected unaffected by whether umask stripping is done by the VFS
+itself (if no POSIX ACLs are supported or enabled) or in the filesystem
+in posix_acl_create() (if POSIX ACLs are supported).
+
+The vfs_prepare_mode() helper is called directly in vfs_*() helpers that
+create new filesystem objects. We need to move them into there to make
+sure that filesystems like overlayfs hat have callchains like:
+
+sys_mknod()
+-> do_mknodat(mode)
+   -> .mknod = ovl_mknod(mode)
+      -> ovl_create(mode)
+         -> vfs_mknod(mode)
+
+get S_ISGID stripping done when calling into lower filesystems via
+vfs_*() creation helpers. Moving vfs_prepare_mode() into e.g.
+vfs_mknod() takes care of that. This is in any case semantically cleaner
+because S_ISGID stripping is VFS security requirement.
+
+Security hooks so far have seen the mode with the umask applied but
+without S_ISGID handling done. The relevant hooks are called outside of
+vfs_*() creation helpers so by calling vfs_prepare_mode() from vfs_*()
+helpers the security hooks would now see the mode without umask
+stripping applied. For now we fix this by passing the mode with umask
+settings applied to not risk any regressions for LSM hooks. IOW, nothing
+changes for LSM hooks. It is worth pointing out that security hooks
+never saw the mode that is seen by the filesystem when actually creating
+the file. They have always been completely misplaced for that to work.
+
+The following filesystems use inode_init_owner() and thus relied on
+S_ISGID stripping: spufs, 9p, bfs, btrfs, ext2, ext4, f2fs, hfsplus,
+hugetlbfs, jfs, minix, nilfs2, ntfs3, ocfs2, omfs, overlayfs, ramfs,
+reiserfs, sysv, ubifs, udf, ufs, xfs, zonefs, bpf, tmpfs.
+
+All of the above filesystems end up calling inode_init_owner() when new
+filesystem objects are created through the ->mkdir(), ->mknod(),
+->create(), ->tmpfile(), ->rename() inode operations.
+
+Since directories always inherit the S_ISGID bit with the exception of
+xfs when irix_sgid_inherit mode is turned on S_ISGID stripping doesn't
+apply. The ->symlink() and ->link() inode operations trivially inherit
+the mode from the target and the ->rename() inode operation inherits the
+mode from the source inode. All other creation inode operations will get
+S_ISGID handling via vfs_prepare_mode() when called from their relevant
+vfs_*() helpers.
+
+In addition to this there are filesystems which allow the creation of
+filesystem objects through ioctl()s or - in the case of spufs -
+circumventing the vfs in other ways. If filesystem objects are created
+through ioctl()s the vfs doesn't know about it and can't apply regular
+permission checking including S_ISGID logic. Therfore, a filesystem
+relying on S_ISGID stripping in inode_init_owner() in their ioctl()
+callpath will be affected by moving this logic into the vfs. We audited
+those filesystems:
+
+* btrfs allows the creation of filesystem objects through various
+  ioctls(). Snapshot creation literally takes a snapshot and so the mode
+  is fully preserved and S_ISGID stripping doesn't apply.
+
+  Creating a new subvolum relies on inode_init_owner() in
+  btrfs_new_subvol_inode() but only creates directories and doesn't
+  raise S_ISGID.
+
+* ocfs2 has a peculiar implementation of reflinks. In contrast to e.g.
+  xfs and btrfs FICLONE/FICLONERANGE ioctl() that is only concerned with
+  the actual extents ocfs2 uses a separate ioctl() that also creates the
+  target file.
+
+  Iow, ocfs2 circumvents the vfs entirely here and did indeed rely on
+  inode_init_owner() to strip the S_ISGID bit. This is the only place
+  where a filesystem needs to call mode_strip_sgid() directly but this
+  is self-inflicted pain.
+
+* spufs doesn't go through the vfs at all and doesn't use ioctl()s
+  either. Instead it has a dedicated system call spufs_create() which
+  allows the creation of filesystem objects. But spufs only creates
+  directories and doesn't allo S_SIGID bits, i.e. it specifically only
+  allows 0777 bits.
+
+* bpf uses vfs_mkobj() but also doesn't allow S_ISGID bits to be created.
+
+The patch will have an effect on ext2 when the EXT2_MOUNT_GRPID mount
+option is used, on ext4 when the EXT4_MOUNT_GRPID mount option is used,
+and on xfs when the XFS_FEAT_GRPID mount option is used. When any of
+these filesystems are mounted with their respective GRPID option then
+newly created files inherit the parent directories group
+unconditionally. In these cases non of the filesystems call
+inode_init_owner() and thus did never strip the S_ISGID bit for newly
+created files. Moving this logic into the VFS means that they now get
+the S_ISGID bit stripped. This is a user visible change. If this leads
+to regressions we will either need to figure out a better way or we need
+to revert. However, given the various setgid bugs that we found just in
+the last two years this is a regression risk we should take.
+
+Associated with this change is a new set of fstests to enforce the
+semantics for all new filesystems.
+
+Link: https://lore.kernel.org/ceph-devel/20220427092201.wvsdjbnc7b4dttaw@wittgenstein [1]
+Link: e014f37db1a2 ("xfs: use setattr_copy to set vfs inode attributes") [2]
+Link: 01ea173e103e ("xfs: fix up non-directory creation in SGID directories") [3]
+Link: fd84bfdddd16 ("ceph: fix up non-directory creation in SGID directories") [4]
+Link: https://lore.kernel.org/r/1657779088-2242-3-git-send-email-xuyang2018.jy@fujitsu.com
+Suggested-by: Dave Chinner <david@fromorbit.com>
+Suggested-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-and-Tested-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
+[<brauner@kernel.org>: rewrote commit message]
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/inode.c       |  2 --
+ fs/namei.c       | 82 ++++++++++++++++++++++++++++++++++++++++--------
+ fs/ocfs2/namei.c |  1 +
+ 3 files changed, 70 insertions(+), 15 deletions(-)
+
+diff --git a/fs/inode.c b/fs/inode.c
+index 3740102c9bd5e..957b2d18ec29f 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -2165,8 +2165,6 @@ void inode_init_owner(struct user_namespace *mnt_userns, struct inode *inode,
+               /* Directories are special, and always inherit S_ISGID */
+               if (S_ISDIR(mode))
+                       mode |= S_ISGID;
+-              else
+-                      mode = mode_strip_sgid(mnt_userns, dir, mode);
+       } else
+               inode_fsgid_set(inode, mnt_userns);
+       inode->i_mode = mode;
+diff --git a/fs/namei.c b/fs/namei.c
+index 81b31d9a063f2..02e99606c65be 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -3000,6 +3000,65 @@ void unlock_rename(struct dentry *p1, struct dentry *p2)
+ }
+ EXPORT_SYMBOL(unlock_rename);
++/**
++ * mode_strip_umask - handle vfs umask stripping
++ * @dir:      parent directory of the new inode
++ * @mode:     mode of the new inode to be created in @dir
++ *
++ * Umask stripping depends on whether or not the filesystem supports POSIX
++ * ACLs. If the filesystem doesn't support it umask stripping is done directly
++ * in here. If the filesystem does support POSIX ACLs umask stripping is
++ * deferred until the filesystem calls posix_acl_create().
++ *
++ * Returns: mode
++ */
++static inline umode_t mode_strip_umask(const struct inode *dir, umode_t mode)
++{
++      if (!IS_POSIXACL(dir))
++              mode &= ~current_umask();
++      return mode;
++}
++
++/**
++ * vfs_prepare_mode - prepare the mode to be used for a new inode
++ * @mnt_userns:               user namespace of the mount the inode was found from
++ * @dir:      parent directory of the new inode
++ * @mode:     mode of the new inode
++ * @mask_perms:       allowed permission by the vfs
++ * @type:     type of file to be created
++ *
++ * This helper consolidates and enforces vfs restrictions on the @mode of a new
++ * object to be created.
++ *
++ * Umask stripping depends on whether the filesystem supports POSIX ACLs (see
++ * the kernel documentation for mode_strip_umask()). Moving umask stripping
++ * after setgid stripping allows the same ordering for both non-POSIX ACL and
++ * POSIX ACL supporting filesystems.
++ *
++ * Note that it's currently valid for @type to be 0 if a directory is created.
++ * Filesystems raise that flag individually and we need to check whether each
++ * filesystem can deal with receiving S_IFDIR from the vfs before we enforce a
++ * non-zero type.
++ *
++ * Returns: mode to be passed to the filesystem
++ */
++static inline umode_t vfs_prepare_mode(struct user_namespace *mnt_userns,
++                                     const struct inode *dir, umode_t mode,
++                                     umode_t mask_perms, umode_t type)
++{
++      mode = mode_strip_sgid(mnt_userns, dir, mode);
++      mode = mode_strip_umask(dir, mode);
++
++      /*
++       * Apply the vfs mandated allowed permission mask and set the type of
++       * file to be created before we call into the filesystem.
++       */
++      mode &= (mask_perms & ~S_IFMT);
++      mode |= (type & S_IFMT);
++
++      return mode;
++}
++
+ /**
+  * vfs_create - create new file
+  * @mnt_userns:       user namespace of the mount the inode was found from
+@@ -3025,8 +3084,8 @@ int vfs_create(struct user_namespace *mnt_userns, struct inode *dir,
+       if (!dir->i_op->create)
+               return -EACCES; /* shouldn't it be ENOSYS? */
+-      mode &= S_IALLUGO;
+-      mode |= S_IFREG;
++
++      mode = vfs_prepare_mode(mnt_userns, dir, mode, S_IALLUGO, S_IFREG);
+       error = security_inode_create(dir, dentry, mode);
+       if (error)
+               return error;
+@@ -3291,8 +3350,7 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
+       if (open_flag & O_CREAT) {
+               if (open_flag & O_EXCL)
+                       open_flag &= ~O_TRUNC;
+-              if (!IS_POSIXACL(dir->d_inode))
+-                      mode &= ~current_umask();
++              mode = vfs_prepare_mode(mnt_userns, dir->d_inode, mode, mode, mode);
+               if (likely(got_write))
+                       create_error = may_o_create(mnt_userns, &nd->path,
+                                                   dentry, mode);
+@@ -3525,8 +3583,7 @@ struct dentry *vfs_tmpfile(struct user_namespace *mnt_userns,
+       child = d_alloc(dentry, &slash_name);
+       if (unlikely(!child))
+               goto out_err;
+-      if (!IS_POSIXACL(dir))
+-              mode &= ~current_umask();
++      mode = vfs_prepare_mode(mnt_userns, dir, mode, mode, mode);
+       error = dir->i_op->tmpfile(mnt_userns, dir, child, mode);
+       if (error)
+               goto out_err;
+@@ -3804,6 +3861,7 @@ int vfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+       if (!dir->i_op->mknod)
+               return -EPERM;
++      mode = vfs_prepare_mode(mnt_userns, dir, mode, mode, mode);
+       error = devcgroup_inode_mknod(mode, dev);
+       if (error)
+               return error;
+@@ -3854,9 +3912,8 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
+       if (IS_ERR(dentry))
+               goto out1;
+-      if (!IS_POSIXACL(path.dentry->d_inode))
+-              mode &= ~current_umask();
+-      error = security_path_mknod(&path, dentry, mode, dev);
++      error = security_path_mknod(&path, dentry,
++                      mode_strip_umask(path.dentry->d_inode, mode), dev);
+       if (error)
+               goto out2;
+@@ -3926,7 +3983,7 @@ int vfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
+       if (!dir->i_op->mkdir)
+               return -EPERM;
+-      mode &= (S_IRWXUGO|S_ISVTX);
++      mode = vfs_prepare_mode(mnt_userns, dir, mode, S_IRWXUGO | S_ISVTX, 0);
+       error = security_inode_mkdir(dir, dentry, mode);
+       if (error)
+               return error;
+@@ -3954,9 +4011,8 @@ int do_mkdirat(int dfd, struct filename *name, umode_t mode)
+       if (IS_ERR(dentry))
+               goto out_putname;
+-      if (!IS_POSIXACL(path.dentry->d_inode))
+-              mode &= ~current_umask();
+-      error = security_path_mkdir(&path, dentry, mode);
++      error = security_path_mkdir(&path, dentry,
++                      mode_strip_umask(path.dentry->d_inode, mode));
+       if (!error) {
+               struct user_namespace *mnt_userns;
+               mnt_userns = mnt_user_ns(path.mnt);
+diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
+index 11807034dd483..5b8237ceb8cce 100644
+--- a/fs/ocfs2/namei.c
++++ b/fs/ocfs2/namei.c
+@@ -197,6 +197,7 @@ static struct inode *ocfs2_get_init_inode(struct inode *dir, umode_t mode)
+        * callers. */
+       if (S_ISDIR(mode))
+               set_nlink(inode, 2);
++      mode = mode_strip_sgid(&init_user_ns, dir, mode);
+       inode_init_owner(&init_user_ns, inode, dir, mode);
+       status = dquot_initialize(inode);
+       if (status)
+-- 
+2.39.2
+
diff --git a/queue-5.15/fs-move-should_remove_suid.patch b/queue-5.15/fs-move-should_remove_suid.patch
new file mode 100644 (file)
index 0000000..a44c00f
--- /dev/null
@@ -0,0 +1,108 @@
+From 848d854458122c791de5912b9de0f621badb04bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:19 -0800
+Subject: fs: move should_remove_suid()
+
+From: Christian Brauner <brauner@kernel.org>
+
+commit e243e3f94c804ecca9a8241b5babe28f35258ef4 upstream.
+
+Move the helper from inode.c to attr.c. This keeps the the core of the
+set{g,u}id stripping logic in one place when we add follow-up changes.
+It is the better place anyway, since should_remove_suid() returns
+ATTR_KILL_S{G,U}ID flags.
+
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/attr.c  | 29 +++++++++++++++++++++++++++++
+ fs/inode.c | 29 -----------------------------
+ 2 files changed, 29 insertions(+), 29 deletions(-)
+
+diff --git a/fs/attr.c b/fs/attr.c
+index 686840aa91c8b..f045431bab1ad 100644
+--- a/fs/attr.c
++++ b/fs/attr.c
+@@ -20,6 +20,35 @@
+ #include "internal.h"
++/*
++ * The logic we want is
++ *
++ *    if suid or (sgid and xgrp)
++ *            remove privs
++ */
++int should_remove_suid(struct dentry *dentry)
++{
++      umode_t mode = d_inode(dentry)->i_mode;
++      int kill = 0;
++
++      /* suid always must be killed */
++      if (unlikely(mode & S_ISUID))
++              kill = ATTR_KILL_SUID;
++
++      /*
++       * sgid without any exec bits is just a mandatory locking mark; leave
++       * it alone.  If some exec bits are set, it's a real sgid; kill it.
++       */
++      if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
++              kill |= ATTR_KILL_SGID;
++
++      if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
++              return kill;
++
++      return 0;
++}
++EXPORT_SYMBOL(should_remove_suid);
++
+ /**
+  * chown_ok - verify permissions to chown inode
+  * @mnt_userns:       user namespace of the mount @inode was found from
+diff --git a/fs/inode.c b/fs/inode.c
+index a71fb82279bb1..3811269259e11 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -1864,35 +1864,6 @@ void touch_atime(const struct path *path)
+ }
+ EXPORT_SYMBOL(touch_atime);
+-/*
+- * The logic we want is
+- *
+- *    if suid or (sgid and xgrp)
+- *            remove privs
+- */
+-int should_remove_suid(struct dentry *dentry)
+-{
+-      umode_t mode = d_inode(dentry)->i_mode;
+-      int kill = 0;
+-
+-      /* suid always must be killed */
+-      if (unlikely(mode & S_ISUID))
+-              kill = ATTR_KILL_SUID;
+-
+-      /*
+-       * sgid without any exec bits is just a mandatory locking mark; leave
+-       * it alone.  If some exec bits are set, it's a real sgid; kill it.
+-       */
+-      if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
+-              kill |= ATTR_KILL_SGID;
+-
+-      if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode)))
+-              return kill;
+-
+-      return 0;
+-}
+-EXPORT_SYMBOL(should_remove_suid);
+-
+ /*
+  * Return mask of changes for notify_change() that need to be done as a
+  * response to write or truncate. Return 0 if nothing has to be changed.
+-- 
+2.39.2
+
diff --git a/queue-5.15/fs-use-consistent-setgid-checks-in-is_sxid.patch b/queue-5.15/fs-use-consistent-setgid-checks-in-is_sxid.patch
new file mode 100644 (file)
index 0000000..cfc187e
--- /dev/null
@@ -0,0 +1,46 @@
+From 3a27dd1a0eb7c05d001d126d952f5075d5cb3cfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:22 -0800
+Subject: fs: use consistent setgid checks in is_sxid()
+
+From: Christian Brauner <brauner@kernel.org>
+
+commit 8d84e39d76bd83474b26cb44f4b338635676e7e8 upstream.
+
+Now that we made the VFS setgid checking consistent an inode can't be
+marked security irrelevant even if the setgid bit is still set. Make
+this function consistent with all other helpers.
+
+Note that enforcing consistent setgid stripping checks for file
+modification and mode- and ownership changes will cause the setgid bit
+to be lost in more cases than useed to be the case. If an unprivileged
+user wrote to a non-executable setgid file that they don't have
+privilege over the setgid bit will be dropped. This will lead to
+temporary failures in some xfstests until they have been updated.
+
+Reported-by: Miklos Szeredi <miklos@szeredi.hu>
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/fs.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 9601c2d774c88..23ecfecdc4504 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -3571,7 +3571,7 @@ int __init list_bdev_fs_names(char *buf, size_t size);
+ static inline bool is_sxid(umode_t mode)
+ {
+-      return (mode & S_ISUID) || ((mode & S_ISGID) && (mode & S_IXGRP));
++      return mode & (S_ISUID | S_ISGID);
+ }
+ static inline int check_sticky(struct user_namespace *mnt_userns,
+-- 
+2.39.2
+
diff --git a/queue-5.15/iommu-amd-add-a-length-limitation-for-the-ivrs_acpih.patch b/queue-5.15/iommu-amd-add-a-length-limitation-for-the-ivrs_acpih.patch
new file mode 100644 (file)
index 0000000..5d451ca
--- /dev/null
@@ -0,0 +1,73 @@
+From f95bbac94d96e3d7999c616778397948e788d500 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 08:26:56 +0000
+Subject: iommu/amd: Add a length limitation for the ivrs_acpihid command-line
+ parameter
+
+From: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+
+[ Upstream commit b6b26d86c61c441144c72f842f7469bb686e1211 ]
+
+The 'acpiid' buffer in the parse_ivrs_acpihid function may overflow,
+because the string specifier in the format string sscanf()
+has no width limitation.
+
+Found by InfoTeCS on behalf of Linux Verification Center
+(linuxtesting.org) with SVACE.
+
+Fixes: ca3bf5d47cec ("iommu/amd: Introduces ivrs_acpihid kernel parameter")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ilia.Gavrilov <Ilia.Gavrilov@infotecs.ru>
+Reviewed-by: Kim Phillips <kim.phillips@amd.com>
+Link: https://lore.kernel.org/r/20230202082719.1513849-1-Ilia.Gavrilov@infotecs.ru
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/init.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index 6c11db3356f78..50ea582be5910 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -3224,15 +3224,26 @@ static int __init parse_ivrs_hpet(char *str)
+       return 1;
+ }
++#define ACPIID_LEN (ACPIHID_UID_LEN + ACPIHID_HID_LEN)
++
+ static int __init parse_ivrs_acpihid(char *str)
+ {
+       u32 seg = 0, bus, dev, fn;
+       char *hid, *uid, *p, *addr;
+-      char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0};
++      char acpiid[ACPIID_LEN] = {0};
+       int i;
+       addr = strchr(str, '@');
+       if (!addr) {
++              addr = strchr(str, '=');
++              if (!addr)
++                      goto not_found;
++
++              ++addr;
++
++              if (strlen(addr) > ACPIID_LEN)
++                      goto not_found;
++
+               if (sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid) == 4 ||
+                   sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid) == 5) {
+                       pr_warn("ivrs_acpihid%s option format deprecated; use ivrs_acpihid=%s@%04x:%02x:%02x.%d instead\n",
+@@ -3245,6 +3256,9 @@ static int __init parse_ivrs_acpihid(char *str)
+       /* We have the '@', make it the terminator to get just the acpiid */
+       *addr++ = 0;
++      if (strlen(str) > ACPIID_LEN + 1)
++              goto not_found;
++
+       if (sscanf(str, "=%s", acpiid) != 1)
+               goto not_found;
+-- 
+2.39.2
+
diff --git a/queue-5.15/iommu-amd-add-pci-segment-support-for-ivrs_-ioapic-h.patch b/queue-5.15/iommu-amd-add-pci-segment-support-for-ivrs_-ioapic-h.patch
new file mode 100644 (file)
index 0000000..ddf85b8
--- /dev/null
@@ -0,0 +1,193 @@
+From 3c18ee515ee86665867f0292e4e06c1541c257cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 17:08:22 +0530
+Subject: iommu/amd: Add PCI segment support for ivrs_[ioapic/hpet/acpihid]
+ commands
+
+From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+
+[ Upstream commit bbe3a106580c21bc883fb0c9fa3da01534392fe8 ]
+
+By default, PCI segment is zero and can be omitted. To support system
+with non-zero PCI segment ID, modify the parsing functions to allow
+PCI segment ID.
+
+Co-developed-by: Vasant Hegde <vasant.hegde@amd.com>
+Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
+Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Link: https://lore.kernel.org/r/20220706113825.25582-33-vasant.hegde@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Stable-dep-of: b6b26d86c61c ("iommu/amd: Add a length limitation for the ivrs_acpihid command-line parameter")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../admin-guide/kernel-parameters.txt         | 34 ++++++++++----
+ drivers/iommu/amd/init.c                      | 44 ++++++++++++-------
+ 2 files changed, 52 insertions(+), 26 deletions(-)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index bcb102c91b190..d49437b9a6980 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -2200,23 +2200,39 @@
+       ivrs_ioapic     [HW,X86-64]
+                       Provide an override to the IOAPIC-ID<->DEVICE-ID
+-                      mapping provided in the IVRS ACPI table. For
+-                      example, to map IOAPIC-ID decimal 10 to
+-                      PCI device 00:14.0 write the parameter as:
++                      mapping provided in the IVRS ACPI table.
++                      By default, PCI segment is 0, and can be omitted.
++                      For example:
++                      * To map IOAPIC-ID decimal 10 to PCI device 00:14.0
++                        write the parameter as:
+                               ivrs_ioapic[10]=00:14.0
++                      * To map IOAPIC-ID decimal 10 to PCI segment 0x1 and
++                        PCI device 00:14.0 write the parameter as:
++                              ivrs_ioapic[10]=0001:00:14.0
+       ivrs_hpet       [HW,X86-64]
+                       Provide an override to the HPET-ID<->DEVICE-ID
+-                      mapping provided in the IVRS ACPI table. For
+-                      example, to map HPET-ID decimal 0 to
+-                      PCI device 00:14.0 write the parameter as:
++                      mapping provided in the IVRS ACPI table.
++                      By default, PCI segment is 0, and can be omitted.
++                      For example:
++                      * To map HPET-ID decimal 0 to PCI device 00:14.0
++                        write the parameter as:
+                               ivrs_hpet[0]=00:14.0
++                      * To map HPET-ID decimal 10 to PCI segment 0x1 and
++                        PCI device 00:14.0 write the parameter as:
++                              ivrs_ioapic[10]=0001:00:14.0
+       ivrs_acpihid    [HW,X86-64]
+                       Provide an override to the ACPI-HID:UID<->DEVICE-ID
+-                      mapping provided in the IVRS ACPI table. For
+-                      example, to map UART-HID:UID AMD0020:0 to
+-                      PCI device 00:14.5 write the parameter as:
++                      mapping provided in the IVRS ACPI table.
++
++                      For example, to map UART-HID:UID AMD0020:0 to
++                      PCI segment 0x1 and PCI device ID 00:14.5,
++                      write the parameter as:
++                              ivrs_acpihid[0001:00:14.5]=AMD0020:0
++
++                      By default, PCI segment is 0, and can be omitted.
++                      For example, PCI device 00:14.5 write the parameter as:
+                               ivrs_acpihid[00:14.5]=AMD0020:0
+       js=             [HW,JOY] Analog joystick
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index ce91a6d8532f3..6961fe80e8eea 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -85,6 +85,10 @@
+ #define ACPI_DEVFLAG_ATSDIS             0x10000000
+ #define LOOP_TIMEOUT  2000000
++
++#define IVRS_GET_SBDF_ID(seg, bus, dev, fd)   (((seg & 0xffff) << 16) | ((bus & 0xff) << 8) \
++                                               | ((dev & 0x1f) << 3) | (fn & 0x7))
++
+ /*
+  * ACPI table definitions
+  *
+@@ -3146,15 +3150,17 @@ static int __init parse_amd_iommu_options(char *str)
+ static int __init parse_ivrs_ioapic(char *str)
+ {
+-      unsigned int bus, dev, fn;
++      u32 seg = 0, bus, dev, fn;
+       int ret, id, i;
+-      u16 devid;
++      u32 devid;
+       ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
+-
+       if (ret != 4) {
+-              pr_err("Invalid command line: ivrs_ioapic%s\n", str);
+-              return 1;
++              ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
++              if (ret != 5) {
++                      pr_err("Invalid command line: ivrs_ioapic%s\n", str);
++                      return 1;
++              }
+       }
+       if (early_ioapic_map_size == EARLY_MAP_SIZE) {
+@@ -3163,7 +3169,7 @@ static int __init parse_ivrs_ioapic(char *str)
+               return 1;
+       }
+-      devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
++      devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);
+       cmdline_maps                    = true;
+       i                               = early_ioapic_map_size++;
+@@ -3176,15 +3182,17 @@ static int __init parse_ivrs_ioapic(char *str)
+ static int __init parse_ivrs_hpet(char *str)
+ {
+-      unsigned int bus, dev, fn;
++      u32 seg = 0, bus, dev, fn;
+       int ret, id, i;
+-      u16 devid;
++      u32 devid;
+       ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
+-
+       if (ret != 4) {
+-              pr_err("Invalid command line: ivrs_hpet%s\n", str);
+-              return 1;
++              ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
++              if (ret != 5) {
++                      pr_err("Invalid command line: ivrs_hpet%s\n", str);
++                      return 1;
++              }
+       }
+       if (early_hpet_map_size == EARLY_MAP_SIZE) {
+@@ -3193,7 +3201,7 @@ static int __init parse_ivrs_hpet(char *str)
+               return 1;
+       }
+-      devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
++      devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);
+       cmdline_maps                    = true;
+       i                               = early_hpet_map_size++;
+@@ -3206,15 +3214,18 @@ static int __init parse_ivrs_hpet(char *str)
+ static int __init parse_ivrs_acpihid(char *str)
+ {
+-      u32 bus, dev, fn;
++      u32 seg = 0, bus, dev, fn;
+       char *hid, *uid, *p;
+       char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0};
+       int ret, i;
+       ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid);
+       if (ret != 4) {
+-              pr_err("Invalid command line: ivrs_acpihid(%s)\n", str);
+-              return 1;
++              ret = sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid);
++              if (ret != 5) {
++                      pr_err("Invalid command line: ivrs_acpihid(%s)\n", str);
++                      return 1;
++              }
+       }
+       p = acpiid;
+@@ -3236,8 +3247,7 @@ static int __init parse_ivrs_acpihid(char *str)
+       i = early_acpihid_map_size++;
+       memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
+       memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
+-      early_acpihid_map[i].devid =
+-              ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7);
++      early_acpihid_map[i].devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn);
+       early_acpihid_map[i].cmd_line   = true;
+       return 1;
+-- 
+2.39.2
+
diff --git a/queue-5.15/iommu-amd-fix-ill-formed-ivrs_ioapic-ivrs_hpet-and-i.patch b/queue-5.15/iommu-amd-fix-ill-formed-ivrs_ioapic-ivrs_hpet-and-i.patch
new file mode 100644 (file)
index 0000000..e8ce90a
--- /dev/null
@@ -0,0 +1,217 @@
+From dc5e3d9d7c18b7f9dcb8bf4c1cf02cfefad299ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Sep 2022 10:56:38 -0500
+Subject: iommu/amd: Fix ill-formed ivrs_ioapic, ivrs_hpet and ivrs_acpihid
+ options
+
+From: Kim Phillips <kim.phillips@amd.com>
+
+[ Upstream commit 1198d2316dc4265a97d0e8445a22c7a6d17580a4 ]
+
+Currently, these options cause the following libkmod error:
+
+libkmod: ERROR ../libkmod/libkmod-config.c:489 kcmdline_parse_result: \
+       Ignoring bad option on kernel command line while parsing module \
+       name: 'ivrs_xxxx[XX:XX'
+
+Fix by introducing a new parameter format for these options and
+throw a warning for the deprecated format.
+
+Users are still allowed to omit the PCI Segment if zero.
+
+Adding a Link: to the reason why we're modding the syntax parsing
+in the driver and not in libkmod.
+
+Fixes: ca3bf5d47cec ("iommu/amd: Introduces ivrs_acpihid kernel parameter")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/linux-modules/20200310082308.14318-2-lucas.demarchi@intel.com/
+Reported-by: Kim Phillips <kim.phillips@amd.com>
+Co-developed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Signed-off-by: Kim Phillips <kim.phillips@amd.com>
+Link: https://lore.kernel.org/r/20220919155638.391481-2-kim.phillips@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Stable-dep-of: b6b26d86c61c ("iommu/amd: Add a length limitation for the ivrs_acpihid command-line parameter")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../admin-guide/kernel-parameters.txt         | 27 +++++--
+ drivers/iommu/amd/init.c                      | 79 +++++++++++++------
+ 2 files changed, 76 insertions(+), 30 deletions(-)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index d49437b9a6980..4dbbc95316691 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -2202,7 +2202,13 @@
+                       Provide an override to the IOAPIC-ID<->DEVICE-ID
+                       mapping provided in the IVRS ACPI table.
+                       By default, PCI segment is 0, and can be omitted.
+-                      For example:
++
++                      For example, to map IOAPIC-ID decimal 10 to
++                      PCI segment 0x1 and PCI device 00:14.0,
++                      write the parameter as:
++                              ivrs_ioapic=10@0001:00:14.0
++
++                      Deprecated formats:
+                       * To map IOAPIC-ID decimal 10 to PCI device 00:14.0
+                         write the parameter as:
+                               ivrs_ioapic[10]=00:14.0
+@@ -2214,7 +2220,13 @@
+                       Provide an override to the HPET-ID<->DEVICE-ID
+                       mapping provided in the IVRS ACPI table.
+                       By default, PCI segment is 0, and can be omitted.
+-                      For example:
++
++                      For example, to map HPET-ID decimal 10 to
++                      PCI segment 0x1 and PCI device 00:14.0,
++                      write the parameter as:
++                              ivrs_hpet=10@0001:00:14.0
++
++                      Deprecated formats:
+                       * To map HPET-ID decimal 0 to PCI device 00:14.0
+                         write the parameter as:
+                               ivrs_hpet[0]=00:14.0
+@@ -2225,15 +2237,20 @@
+       ivrs_acpihid    [HW,X86-64]
+                       Provide an override to the ACPI-HID:UID<->DEVICE-ID
+                       mapping provided in the IVRS ACPI table.
++                      By default, PCI segment is 0, and can be omitted.
+                       For example, to map UART-HID:UID AMD0020:0 to
+                       PCI segment 0x1 and PCI device ID 00:14.5,
+                       write the parameter as:
+-                              ivrs_acpihid[0001:00:14.5]=AMD0020:0
++                              ivrs_acpihid=AMD0020:0@0001:00:14.5
+-                      By default, PCI segment is 0, and can be omitted.
+-                      For example, PCI device 00:14.5 write the parameter as:
++                      Deprecated formats:
++                      * To map UART-HID:UID AMD0020:0 to PCI segment is 0,
++                        PCI device ID 00:14.5, write the parameter as:
+                               ivrs_acpihid[00:14.5]=AMD0020:0
++                      * To map UART-HID:UID AMD0020:0 to PCI segment 0x1 and
++                        PCI device ID 00:14.5, write the parameter as:
++                              ivrs_acpihid[0001:00:14.5]=AMD0020:0
+       js=             [HW,JOY] Analog joystick
+                       See Documentation/input/joydev/joystick.rst.
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index 6961fe80e8eea..6c11db3356f78 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -3151,18 +3151,24 @@ static int __init parse_amd_iommu_options(char *str)
+ static int __init parse_ivrs_ioapic(char *str)
+ {
+       u32 seg = 0, bus, dev, fn;
+-      int ret, id, i;
++      int id, i;
+       u32 devid;
+-      ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
+-      if (ret != 4) {
+-              ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
+-              if (ret != 5) {
+-                      pr_err("Invalid command line: ivrs_ioapic%s\n", str);
+-                      return 1;
+-              }
++      if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++          sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
++              goto found;
++
++      if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++          sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
++              pr_warn("ivrs_ioapic%s option format deprecated; use ivrs_ioapic=%d@%04x:%02x:%02x.%d instead\n",
++                      str, id, seg, bus, dev, fn);
++              goto found;
+       }
++      pr_err("Invalid command line: ivrs_ioapic%s\n", str);
++      return 1;
++
++found:
+       if (early_ioapic_map_size == EARLY_MAP_SIZE) {
+               pr_err("Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n",
+                       str);
+@@ -3183,18 +3189,24 @@ static int __init parse_ivrs_ioapic(char *str)
+ static int __init parse_ivrs_hpet(char *str)
+ {
+       u32 seg = 0, bus, dev, fn;
+-      int ret, id, i;
++      int id, i;
+       u32 devid;
+-      ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
+-      if (ret != 4) {
+-              ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
+-              if (ret != 5) {
+-                      pr_err("Invalid command line: ivrs_hpet%s\n", str);
+-                      return 1;
+-              }
++      if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++          sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
++              goto found;
++
++      if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++          sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
++              pr_warn("ivrs_hpet%s option format deprecated; use ivrs_hpet=%d@%04x:%02x:%02x.%d instead\n",
++                      str, id, seg, bus, dev, fn);
++              goto found;
+       }
++      pr_err("Invalid command line: ivrs_hpet%s\n", str);
++      return 1;
++
++found:
+       if (early_hpet_map_size == EARLY_MAP_SIZE) {
+               pr_err("Early HPET map overflow - ignoring ivrs_hpet%s\n",
+                       str);
+@@ -3215,19 +3227,36 @@ static int __init parse_ivrs_hpet(char *str)
+ static int __init parse_ivrs_acpihid(char *str)
+ {
+       u32 seg = 0, bus, dev, fn;
+-      char *hid, *uid, *p;
++      char *hid, *uid, *p, *addr;
+       char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0};
+-      int ret, i;
+-
+-      ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid);
+-      if (ret != 4) {
+-              ret = sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid);
+-              if (ret != 5) {
+-                      pr_err("Invalid command line: ivrs_acpihid(%s)\n", str);
+-                      return 1;
++      int i;
++
++      addr = strchr(str, '@');
++      if (!addr) {
++              if (sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid) == 4 ||
++                  sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid) == 5) {
++                      pr_warn("ivrs_acpihid%s option format deprecated; use ivrs_acpihid=%s@%04x:%02x:%02x.%d instead\n",
++                              str, acpiid, seg, bus, dev, fn);
++                      goto found;
+               }
++              goto not_found;
+       }
++      /* We have the '@', make it the terminator to get just the acpiid */
++      *addr++ = 0;
++
++      if (sscanf(str, "=%s", acpiid) != 1)
++              goto not_found;
++
++      if (sscanf(addr, "%x:%x.%x", &bus, &dev, &fn) == 3 ||
++          sscanf(addr, "%x:%x:%x.%x", &seg, &bus, &dev, &fn) == 4)
++              goto found;
++
++not_found:
++      pr_err("Invalid command line: ivrs_acpihid%s\n", str);
++      return 1;
++
++found:
+       p = acpiid;
+       hid = strsep(&p, ":");
+       uid = p;
+-- 
+2.39.2
+
diff --git a/queue-5.15/irqdomain-fix-mapping-creation-race.patch b/queue-5.15/irqdomain-fix-mapping-creation-race.patch
new file mode 100644 (file)
index 0000000..346d91c
--- /dev/null
@@ -0,0 +1,184 @@
+From 2c4dbc49aca94706c550e5bea18e1647dc03a001 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Feb 2023 11:42:48 +0100
+Subject: irqdomain: Fix mapping-creation race
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 601363cc08da25747feb87c55573dd54de91d66a ]
+
+Parallel probing of devices that share interrupts (e.g. when a driver
+uses asynchronous probing) can currently result in two mappings for the
+same hardware interrupt to be created due to missing serialisation.
+
+Make sure to hold the irq_domain_mutex when creating mappings so that
+looking for an existing mapping before creating a new one is done
+atomically.
+
+Fixes: 765230b5f084 ("driver-core: add asynchronous probing support for drivers")
+Fixes: b62b2cf5759b ("irqdomain: Fix handling of type settings for existing mappings")
+Link: https://lore.kernel.org/r/YuJXMHoT4ijUxnRb@hovoldconsulting.com
+Cc: stable@vger.kernel.org      # 4.8
+Cc: Dmitry Torokhov <dtor@chromium.org>
+Cc: Jon Hunter <jonathanh@nvidia.com>
+Tested-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Tested-by: Mark-PK Tsai <mark-pk.tsai@mediatek.com>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230213104302.17307-7-johan+linaro@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/irq/irqdomain.c | 64 ++++++++++++++++++++++++++++++------------
+ 1 file changed, 46 insertions(+), 18 deletions(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index f95196063884a..e0b67784ac1e0 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -25,6 +25,9 @@ static DEFINE_MUTEX(irq_domain_mutex);
+ static struct irq_domain *irq_default_domain;
++static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base,
++                                      unsigned int nr_irqs, int node, void *arg,
++                                      bool realloc, const struct irq_affinity_desc *affinity);
+ static void irq_domain_check_hierarchy(struct irq_domain *domain);
+ struct irqchip_fwid {
+@@ -703,9 +706,9 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
+ EXPORT_SYMBOL_GPL(irq_create_direct_mapping);
+ #endif
+-static unsigned int __irq_create_mapping_affinity(struct irq_domain *domain,
+-                                                irq_hw_number_t hwirq,
+-                                                const struct irq_affinity_desc *affinity)
++static unsigned int irq_create_mapping_affinity_locked(struct irq_domain *domain,
++                                                     irq_hw_number_t hwirq,
++                                                     const struct irq_affinity_desc *affinity)
+ {
+       struct device_node *of_node = irq_domain_get_of_node(domain);
+       int virq;
+@@ -720,7 +723,7 @@ static unsigned int __irq_create_mapping_affinity(struct irq_domain *domain,
+               return 0;
+       }
+-      if (irq_domain_associate(domain, virq, hwirq)) {
++      if (irq_domain_associate_locked(domain, virq, hwirq)) {
+               irq_free_desc(virq);
+               return 0;
+       }
+@@ -756,14 +759,20 @@ unsigned int irq_create_mapping_affinity(struct irq_domain *domain,
+               return 0;
+       }
++      mutex_lock(&irq_domain_mutex);
++
+       /* Check if mapping already exists */
+       virq = irq_find_mapping(domain, hwirq);
+       if (virq) {
+               pr_debug("existing mapping on virq %d\n", virq);
+-              return virq;
++              goto out;
+       }
+-      return __irq_create_mapping_affinity(domain, hwirq, affinity);
++      virq = irq_create_mapping_affinity_locked(domain, hwirq, affinity);
++out:
++      mutex_unlock(&irq_domain_mutex);
++
++      return virq;
+ }
+ EXPORT_SYMBOL_GPL(irq_create_mapping_affinity);
+@@ -830,6 +839,8 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
+       if (WARN_ON(type & ~IRQ_TYPE_SENSE_MASK))
+               type &= IRQ_TYPE_SENSE_MASK;
++      mutex_lock(&irq_domain_mutex);
++
+       /*
+        * If we've already configured this interrupt,
+        * don't do it again, or hell will break loose.
+@@ -842,7 +853,7 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
+                * interrupt number.
+                */
+               if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq))
+-                      return virq;
++                      goto out;
+               /*
+                * If the trigger type has not been set yet, then set
+@@ -850,35 +861,45 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
+                */
+               if (irq_get_trigger_type(virq) == IRQ_TYPE_NONE) {
+                       irq_data = irq_get_irq_data(virq);
+-                      if (!irq_data)
+-                              return 0;
++                      if (!irq_data) {
++                              virq = 0;
++                              goto out;
++                      }
+                       irqd_set_trigger_type(irq_data, type);
+-                      return virq;
++                      goto out;
+               }
+               pr_warn("type mismatch, failed to map hwirq-%lu for %s!\n",
+                       hwirq, of_node_full_name(to_of_node(fwspec->fwnode)));
+-              return 0;
++              virq = 0;
++              goto out;
+       }
+       if (irq_domain_is_hierarchy(domain)) {
+-              virq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, fwspec);
+-              if (virq <= 0)
+-                      return 0;
++              virq = irq_domain_alloc_irqs_locked(domain, -1, 1, NUMA_NO_NODE,
++                                                  fwspec, false, NULL);
++              if (virq <= 0) {
++                      virq = 0;
++                      goto out;
++              }
+       } else {
+               /* Create mapping */
+-              virq = __irq_create_mapping_affinity(domain, hwirq, NULL);
++              virq = irq_create_mapping_affinity_locked(domain, hwirq, NULL);
+               if (!virq)
+-                      return virq;
++                      goto out;
+       }
+       irq_data = irq_get_irq_data(virq);
+-      if (WARN_ON(!irq_data))
+-              return 0;
++      if (WARN_ON(!irq_data)) {
++              virq = 0;
++              goto out;
++      }
+       /* Store trigger type */
+       irqd_set_trigger_type(irq_data, type);
++out:
++      mutex_unlock(&irq_domain_mutex);
+       return virq;
+ }
+@@ -1910,6 +1931,13 @@ void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
+       irq_set_handler_data(virq, handler_data);
+ }
++static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base,
++                                      unsigned int nr_irqs, int node, void *arg,
++                                      bool realloc, const struct irq_affinity_desc *affinity)
++{
++      return -EINVAL;
++}
++
+ static void irq_domain_check_hierarchy(struct irq_domain *domain)
+ {
+ }
+-- 
+2.39.2
+
diff --git a/queue-5.15/nbd-use-the-correct-block_device-in-nbd_bdev_reset.patch b/queue-5.15/nbd-use-the-correct-block_device-in-nbd_bdev_reset.patch
new file mode 100644 (file)
index 0000000..ceb7f1a
--- /dev/null
@@ -0,0 +1,82 @@
+From f022ff9b48467b05cf4b294a6bd75d036ae13486 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Mar 2022 07:29:03 +0200
+Subject: nbd: use the correct block_device in nbd_bdev_reset
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 2a852a693f8839bb877fc731ffbc9ece3a9c16d7 ]
+
+The bdev parameter to ->ioctl contains the block device that the ioctl
+is called on, which can be the partition.  But the openers check in
+nbd_bdev_reset really needs to check use the whole device, so switch to
+using that.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20220330052917.2566582-2-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: e5cfefa97bcc ("block: fix scan partition for exclusively open device again")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/nbd.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index c1ef1df42eb66..ade8b839e4458 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -1167,11 +1167,11 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
+       return -ENOSPC;
+ }
+-static void nbd_bdev_reset(struct block_device *bdev)
++static void nbd_bdev_reset(struct nbd_device *nbd)
+ {
+-      if (bdev->bd_openers > 1)
++      if (nbd->disk->part0->bd_openers > 1)
+               return;
+-      set_capacity(bdev->bd_disk, 0);
++      set_capacity(nbd->disk, 0);
+ }
+ static void nbd_parse_flags(struct nbd_device *nbd)
+@@ -1337,7 +1337,7 @@ static int nbd_start_device(struct nbd_device *nbd)
+       return nbd_set_size(nbd, config->bytesize, nbd_blksize(config));
+ }
+-static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *bdev)
++static int nbd_start_device_ioctl(struct nbd_device *nbd)
+ {
+       struct nbd_config *config = nbd->config;
+       int ret;
+@@ -1358,7 +1358,7 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *b
+       flush_workqueue(nbd->recv_workq);
+       mutex_lock(&nbd->config_lock);
+-      nbd_bdev_reset(bdev);
++      nbd_bdev_reset(nbd);
+       /* user requested, ignore socket errors */
+       if (test_bit(NBD_RT_DISCONNECT_REQUESTED, &config->runtime_flags))
+               ret = 0;
+@@ -1372,7 +1372,7 @@ static void nbd_clear_sock_ioctl(struct nbd_device *nbd,
+ {
+       nbd_clear_sock(nbd);
+       __invalidate_device(bdev, true);
+-      nbd_bdev_reset(bdev);
++      nbd_bdev_reset(nbd);
+       if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF,
+                              &nbd->config->runtime_flags))
+               nbd_config_put(nbd);
+@@ -1418,7 +1418,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
+               config->flags = arg;
+               return 0;
+       case NBD_DO_IT:
+-              return nbd_start_device_ioctl(nbd, bdev);
++              return nbd_start_device_ioctl(nbd);
+       case NBD_CLEAR_QUE:
+               /*
+                * This is for compatibility only.  The queue is always cleared
+-- 
+2.39.2
+
index ca89a84a26073d4e7a72b666f6e3ff57c875e558..1b45d68c1aa1d5ba99410b9a85a49da86c2ac94b 100644 (file)
@@ -80,3 +80,25 @@ riscv-use-read_once_nocheck-in-imprecise-unwinding-s.patch
 s390-ftrace-remove-dead-code.patch
 risc-v-don-t-check-text_mutex-during-stop_machine.patch
 ext4-fix-deadlock-during-directory-rename.patch
+irqdomain-fix-mapping-creation-race.patch
+nbd-use-the-correct-block_device-in-nbd_bdev_reset.patch
+iommu-amd-add-pci-segment-support-for-ivrs_-ioapic-h.patch
+iommu-amd-fix-ill-formed-ivrs_ioapic-ivrs_hpet-and-i.patch
+iommu-amd-add-a-length-limitation-for-the-ivrs_acpih.patch
+staging-rtl8723bs-clean-up-comparsions-to-null.patch
+staging-rtl8723bs-placing-opening-braces-in-previous.patch
+staging-rtl8723bs-fix-placement-of-braces.patch
+staging-rtl8723bs-fix-key-store-index-handling.patch
+watch_queue-fix-ioc_watch_queue_set_size-alloc-error.patch
+tpm-eventlog-don-t-abort-tpm_read_log-on-faulty-acpi.patch
+xfs-use-setattr_copy-to-set-vfs-inode-attributes.patch
+xfs-remove-xfs_prealloc_sync.patch
+xfs-fallocate-should-call-file_modified.patch
+xfs-set-prealloc-flag-in-xfs_alloc_file_space.patch
+fs-add-mode_strip_sgid-helper.patch
+fs-move-s_isgid-stripping-into-the-vfs_-helpers.patch
+attr-add-in_group_or_capable.patch
+fs-move-should_remove_suid.patch
+attr-add-setattr_should_drop_sgid.patch
+attr-use-consistent-sgid-stripping-checks.patch
+fs-use-consistent-setgid-checks-in-is_sxid.patch
diff --git a/queue-5.15/staging-rtl8723bs-clean-up-comparsions-to-null.patch b/queue-5.15/staging-rtl8723bs-clean-up-comparsions-to-null.patch
new file mode 100644 (file)
index 0000000..8c49025
--- /dev/null
@@ -0,0 +1,1053 @@
+From 8c5a283820d4ad87f765f895fe00bea5497b10cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 Aug 2021 17:45:33 +0200
+Subject: staging: rtl8723bs: clean up comparsions to NULL
+
+From: Michael Straube <straube.linux@gmail.com>
+
+[ Upstream commit cd1f1450092216b3e39516f8db58869b6fc20575 ]
+
+Clean up comparsions to NULL reported by checkpatch.
+
+x == NULL -> !x
+x != NULL -> x
+
+Signed-off-by: Michael Straube <straube.linux@gmail.com>
+Link: https://lore.kernel.org/r/20210829154533.11054-1-straube.linux@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 05cbcc415c9b ("staging: rtl8723bs: Fix key-store index handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8723bs/core/rtw_ap.c       | 20 ++--
+ drivers/staging/rtl8723bs/core/rtw_cmd.c      | 96 +++++++++----------
+ .../staging/rtl8723bs/core/rtw_ioctl_set.c    |  4 +-
+ drivers/staging/rtl8723bs/core/rtw_mlme.c     |  6 +-
+ drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 56 +++++------
+ drivers/staging/rtl8723bs/core/rtw_security.c |  6 +-
+ .../staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 24 ++---
+ .../staging/rtl8723bs/os_dep/ioctl_linux.c    | 18 ++--
+ drivers/staging/rtl8723bs/os_dep/os_intfs.c   |  4 +-
+ 9 files changed, 117 insertions(+), 117 deletions(-)
+
+diff --git a/drivers/staging/rtl8723bs/core/rtw_ap.c b/drivers/staging/rtl8723bs/core/rtw_ap.c
+index 6064dd6a76b42..674592e914e26 100644
+--- a/drivers/staging/rtl8723bs/core/rtw_ap.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ap.c
+@@ -891,7 +891,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
+               &ie_len,
+               (pbss_network->ie_length - _BEACON_IE_OFFSET_)
+       );
+-      if (p !=  NULL) {
++      if (p) {
+               memcpy(supportRate, p + 2, ie_len);
+               supportRateNum = ie_len;
+       }
+@@ -903,7 +903,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
+               &ie_len,
+               pbss_network->ie_length - _BEACON_IE_OFFSET_
+       );
+-      if (p !=  NULL) {
++      if (p) {
+               memcpy(supportRate + supportRateNum, p + 2, ie_len);
+               supportRateNum += ie_len;
+       }
+@@ -991,7 +991,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
+                       break;
+               }
+-              if ((p == NULL) || (ie_len == 0))
++              if (!p || ie_len == 0)
+                       break;
+       }
+@@ -1021,7 +1021,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
+                               break;
+                       }
+-                      if ((p == NULL) || (ie_len == 0))
++                      if (!p || ie_len == 0)
+                               break;
+               }
+       }
+@@ -1145,7 +1145,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
+       psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->mac_address);
+       if (!psta) {
+               psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->mac_address);
+-              if (psta == NULL)
++              if (!psta)
+                       return _FAIL;
+       }
+@@ -1275,7 +1275,7 @@ u8 rtw_ap_set_pairwise_key(struct adapter *padapter, struct sta_info *psta)
+       }
+       psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
+-      if (psetstakey_para == NULL) {
++      if (!psetstakey_para) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1311,12 +1311,12 @@ static int rtw_ap_set_key(
+       int res = _SUCCESS;
+       pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (pcmd == NULL) {
++      if (!pcmd) {
+               res = _FAIL;
+               goto exit;
+       }
+       psetkeyparm = rtw_zmalloc(sizeof(struct setkey_parm));
+-      if (psetkeyparm == NULL) {
++      if (!psetkeyparm) {
+               kfree(pcmd);
+               res = _FAIL;
+               goto exit;
+@@ -1474,11 +1474,11 @@ static void update_bcn_wps_ie(struct adapter *padapter)
+               &wps_ielen
+       );
+-      if (pwps_ie == NULL || wps_ielen == 0)
++      if (!pwps_ie || wps_ielen == 0)
+               return;
+       pwps_ie_src = pmlmepriv->wps_beacon_ie;
+-      if (pwps_ie_src == NULL)
++      if (!pwps_ie_src)
+               return;
+       wps_offset = (uint)(pwps_ie - ie);
+diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c
+index 93e3a4c9e1159..5f4f603b3b366 100644
+--- a/drivers/staging/rtl8723bs/core/rtw_cmd.c
++++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c
+@@ -251,7 +251,7 @@ int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
+ {
+       unsigned long irqL;
+-      if (obj == NULL)
++      if (!obj)
+               goto exit;
+       /* spin_lock_bh(&queue->lock); */
+@@ -319,7 +319,7 @@ int rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
+       int res = _FAIL;
+       struct adapter *padapter = pcmdpriv->padapter;
+-      if (cmd_obj == NULL)
++      if (!cmd_obj)
+               goto exit;
+       cmd_obj->padapter = padapter;
+@@ -484,7 +484,7 @@ int rtw_cmd_thread(void *context)
+               /* call callback function for post-processed */
+               if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) {
+                       pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
+-                      if (pcmd_callback == NULL) {
++                      if (!pcmd_callback) {
+                               rtw_free_cmd_obj(pcmd);
+                       } else {
+                               /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */
+@@ -503,7 +503,7 @@ int rtw_cmd_thread(void *context)
+       /*  free all cmd_obj resources */
+       do {
+               pcmd = rtw_dequeue_cmd(pcmdpriv);
+-              if (pcmd == NULL) {
++              if (!pcmd) {
+                       rtw_unregister_cmd_alive(padapter);
+                       break;
+               }
+@@ -542,11 +542,11 @@ u8 rtw_sitesurvey_cmd(struct adapter  *padapter, struct ndis_802_11_ssid *ssid,
+               rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1);
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL)
++      if (!ph2c)
+               return _FAIL;
+       psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm));
+-      if (psurveyPara == NULL) {
++      if (!psurveyPara) {
+               kfree(ph2c);
+               return _FAIL;
+       }
+@@ -604,13 +604,13 @@ u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset)
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pbsetdataratepara = rtw_zmalloc(sizeof(struct setdatarate_parm));
+-      if (pbsetdataratepara == NULL) {
++      if (!pbsetdataratepara) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -640,7 +640,7 @@ u8 rtw_createbss_cmd(struct adapter  *padapter)
+       u8 res = _SUCCESS;
+       pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (pcmd == NULL) {
++      if (!pcmd) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -673,7 +673,7 @@ int rtw_startbss_cmd(struct adapter  *padapter, int flags)
+       } else {
+               /* need enqueue, prepare cmd_obj and enqueue */
+               pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (pcmd == NULL) {
++              if (!pcmd) {
+                       res = _FAIL;
+                       goto exit;
+               }
+@@ -725,7 +725,7 @@ u8 rtw_joinbss_cmd(struct adapter  *padapter, struct wlan_network *pnetwork)
+       u8 *ptmp = NULL;
+       pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (pcmd == NULL) {
++      if (!pcmd) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -837,7 +837,7 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueu
+       /* prepare cmd parameter */
+       param = rtw_zmalloc(sizeof(*param));
+-      if (param == NULL) {
++      if (!param) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -846,7 +846,7 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueu
+       if (enqueue) {
+               /* need enqueue, prepare cmd_obj and enqueue */
+               cmdobj = rtw_zmalloc(sizeof(*cmdobj));
+-              if (cmdobj == NULL) {
++              if (!cmdobj) {
+                       res = _FAIL;
+                       kfree(param);
+                       goto exit;
+@@ -874,7 +874,7 @@ u8 rtw_setopmode_cmd(struct adapter  *padapter, enum ndis_802_11_network_infrast
+       psetop = rtw_zmalloc(sizeof(struct setopmode_parm));
+-      if (psetop == NULL) {
++      if (!psetop) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -882,7 +882,7 @@ u8 rtw_setopmode_cmd(struct adapter  *padapter, enum ndis_802_11_network_infrast
+       if (enqueue) {
+               ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (ph2c == NULL) {
++              if (!ph2c) {
+                       kfree(psetop);
+                       res = _FAIL;
+                       goto exit;
+@@ -910,7 +910,7 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 unicast_
+       u8 res = _SUCCESS;
+       psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
+-      if (psetstakey_para == NULL) {
++      if (!psetstakey_para) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -932,14 +932,14 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 unicast_
+       if (enqueue) {
+               ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (ph2c == NULL) {
++              if (!ph2c) {
+                       kfree(psetstakey_para);
+                       res = _FAIL;
+                       goto exit;
+               }
+               psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp));
+-              if (psetstakey_rsp == NULL) {
++              if (!psetstakey_rsp) {
+                       kfree(ph2c);
+                       kfree(psetstakey_para);
+                       res = _FAIL;
+@@ -977,20 +977,20 @@ u8 rtw_clearstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 enqueu
+               }
+       } else {
+               ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (ph2c == NULL) {
++              if (!ph2c) {
+                       res = _FAIL;
+                       goto exit;
+               }
+               psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
+-              if (psetstakey_para == NULL) {
++              if (!psetstakey_para) {
+                       kfree(ph2c);
+                       res = _FAIL;
+                       goto exit;
+               }
+               psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp));
+-              if (psetstakey_rsp == NULL) {
++              if (!psetstakey_rsp) {
+                       kfree(ph2c);
+                       kfree(psetstakey_para);
+                       res = _FAIL;
+@@ -1022,13 +1022,13 @@ u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr)
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       paddbareq_parm = rtw_zmalloc(sizeof(struct addBaReq_parm));
+-      if (paddbareq_parm == NULL) {
++      if (!paddbareq_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1054,13 +1054,13 @@ u8 rtw_reset_securitypriv_cmd(struct adapter *padapter)
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1089,13 +1089,13 @@ u8 rtw_free_assoc_resources_cmd(struct adapter *padapter)
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1125,13 +1125,13 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter)
+       /* only  primary padapter does this cmd */
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1173,7 +1173,7 @@ u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue, u8 swconf
+       /* prepare cmd parameter */
+       setChannelPlan_param = rtw_zmalloc(sizeof(struct SetChannelPlan_param));
+-      if (setChannelPlan_param == NULL) {
++      if (!setChannelPlan_param) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -1182,7 +1182,7 @@ u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue, u8 swconf
+       if (enqueue) {
+               /* need enqueue, prepare cmd_obj and enqueue */
+               pcmdobj = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (pcmdobj == NULL) {
++              if (!pcmdobj) {
+                       kfree(setChannelPlan_param);
+                       res = _FAIL;
+                       goto exit;
+@@ -1432,13 +1432,13 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue)
+       if (enqueue) {
+               ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (ph2c == NULL) {
++              if (!ph2c) {
+                       res = _FAIL;
+                       goto exit;
+               }
+               pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-              if (pdrvextra_cmd_parm == NULL) {
++              if (!pdrvextra_cmd_parm) {
+                       kfree(ph2c);
+                       res = _FAIL;
+                       goto exit;
+@@ -1474,13 +1474,13 @@ u8 rtw_dm_in_lps_wk_cmd(struct adapter *padapter)
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1540,13 +1540,13 @@ u8 rtw_dm_ra_mask_wk_cmd(struct adapter *padapter, u8 *psta)
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1575,13 +1575,13 @@ u8 rtw_ps_cmd(struct adapter *padapter)
+       u8 res = _SUCCESS;
+       ppscmd = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ppscmd == NULL) {
++      if (!ppscmd) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ppscmd);
+               res = _FAIL;
+               goto exit;
+@@ -1647,13 +1647,13 @@ u8 rtw_chk_hi_queue_cmd(struct adapter *padapter)
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1741,13 +1741,13 @@ u8 rtw_c2h_packet_wk_cmd(struct adapter *padapter, u8 *pbuf, u16 length)
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1776,13 +1776,13 @@ u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt)
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+-      if (pdrvextra_cmd_parm == NULL) {
++      if (!pdrvextra_cmd_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -1957,7 +1957,7 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
+       struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf;
+       struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
+-      if (pcmd->parmbuf == NULL)
++      if (!pcmd->parmbuf)
+               goto exit;
+       if (pcmd->res != H2C_SUCCESS)
+@@ -1980,9 +1980,9 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
+       } else {
+               pwlan = rtw_alloc_network(pmlmepriv);
+               spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
+-              if (pwlan == NULL) {
++              if (!pwlan) {
+                       pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue);
+-                      if (pwlan == NULL) {
++                      if (!pwlan) {
+                               spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
+                               goto createbss_cmd_fail;
+                       }
+diff --git a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c
+index 5cfde71766173..8c11daff2d590 100644
+--- a/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c
++++ b/drivers/staging/rtl8723bs/core/rtw_ioctl_set.c
+@@ -370,7 +370,7 @@ u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_s
+       struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
+       u8 res = true;
+-      if (padapter == NULL) {
++      if (!padapter) {
+               res = false;
+               goto exit;
+       }
+@@ -481,7 +481,7 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter)
+               return 0;
+       psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
+-      if (psta == NULL)
++      if (!psta)
+               return 0;
+       short_GI = query_ra_short_GI(psta);
+diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c
+index 952c3e14d1b33..26c40042d2bed 100644
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
+@@ -439,7 +439,7 @@ struct     wlan_network    *rtw_get_oldest_wlan_network(struct __queue *scanned_queue)
+               pwlan = list_entry(plist, struct wlan_network, list);
+               if (!pwlan->fixed) {
+-                      if (oldest == NULL || time_after(oldest->last_scanned, pwlan->last_scanned))
++                      if (!oldest || time_after(oldest->last_scanned, pwlan->last_scanned))
+                               oldest = pwlan;
+               }
+       }
+@@ -542,7 +542,7 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t
+                       /* TODO: don't select network in the same ess as oldest if it's new enough*/
+               }
+-              if (oldest == NULL || time_after(oldest->last_scanned, pnetwork->last_scanned))
++              if (!oldest || time_after(oldest->last_scanned, pnetwork->last_scanned))
+                       oldest = pnetwork;
+       }
+@@ -1816,7 +1816,7 @@ static int rtw_check_join_candidate(struct mlme_priv *mlme
+                       goto exit;
+       }
+-      if (*candidate == NULL || (*candidate)->network.rssi < competitor->network.rssi) {
++      if (!*candidate || (*candidate)->network.rssi < competitor->network.rssi) {
+               *candidate = competitor;
+               updated = true;
+       }
+diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+index 1a4b4c75c4bf5..e923f306cf0c3 100644
+--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
++++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+@@ -742,11 +742,11 @@ unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame)
+       }
+       pstat = rtw_get_stainfo(pstapriv, sa);
+-      if (pstat == NULL) {
++      if (!pstat) {
+               /*  allocate a new one */
+               pstat = rtw_alloc_stainfo(pstapriv, sa);
+-              if (pstat == NULL) {
++              if (!pstat) {
+                       status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
+                       goto auth_fail;
+               }
+@@ -814,7 +814,7 @@ unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame)
+                       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, WLAN_EID_CHALLENGE, (int *)&ie_len,
+                                       len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
+-                      if ((p == NULL) || (ie_len <= 0)) {
++                      if (!p || ie_len <= 0) {
+                               status = WLAN_STATUS_CHALLENGE_FAIL;
+                               goto auth_fail;
+                       }
+@@ -1034,7 +1034,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
+       /*  check if the supported rate is ok */
+       p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, WLAN_EID_SUPP_RATES, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
+-      if (p == NULL) {
++      if (!p) {
+               /*  use our own rate set as statoin used */
+               /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
+               /* supportRateNum = AP_BSSRATE_LEN; */
+@@ -1047,7 +1047,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
+               p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, WLAN_EID_EXT_SUPP_RATES, &ie_len,
+                               pkt_len - WLAN_HDR_A3_LEN - ie_offset);
+-              if (p !=  NULL) {
++              if (p) {
+                       if (supportRateNum <= sizeof(supportRate)) {
+                               memcpy(supportRate+supportRateNum, p+2, ie_len);
+@@ -1294,7 +1294,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
+       /* get a unique AID */
+       if (pstat->aid == 0) {
+               for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
+-                      if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
++                      if (!pstapriv->sta_aid[pstat->aid - 1])
+                               break;
+               /* if (pstat->aid > NUM_STA) { */
+@@ -1940,7 +1940,7 @@ static struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool
+               goto exit;
+       pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
+-      if (pxmitbuf == NULL) {
++      if (!pxmitbuf) {
+               rtw_free_xmitframe(pxmitpriv, pmgntframe);
+               pmgntframe = NULL;
+               goto exit;
+@@ -2293,7 +2293,7 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
+       struct wlan_bssid_ex            *cur_network = &(pmlmeinfo->network);
+       unsigned int    rate_len;
+-      if (da == NULL)
++      if (!da)
+               return;
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+@@ -2617,7 +2617,7 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short
+       __le16 le_tmp;
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL)
++      if (!pmgntframe)
+               return;
+       /* update attribute */
+@@ -2748,7 +2748,7 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
+       __le16 lestatus, le_tmp;
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL)
++      if (!pmgntframe)
+               return;
+       /* update attribute */
+@@ -2836,7 +2836,7 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
+                               break;
+                       }
+-                      if ((pbuf == NULL) || (ie_len == 0)) {
++                      if (!pbuf || ie_len == 0) {
+                               break;
+                       }
+               }
+@@ -2880,7 +2880,7 @@ void issue_assocreq(struct adapter *padapter)
+       u8 vs_ie_length = 0;
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL)
++      if (!pmgntframe)
+               goto exit;
+       /* update attribute */
+@@ -3057,7 +3057,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da,
+       pmlmeinfo = &(pmlmeext->mlmext_info);
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL)
++      if (!pmgntframe)
+               goto exit;
+       /* update attribute */
+@@ -3196,7 +3196,7 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da,
+       struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL)
++      if (!pmgntframe)
+               goto exit;
+       /* update attribute */
+@@ -3309,7 +3309,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da,
+       __le16 le_tmp;
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL) {
++      if (!pmgntframe) {
+               goto exit;
+       }
+@@ -3635,7 +3635,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
+       action = ACT_PUBLIC_BSSCOEXIST;
+       pmgntframe = alloc_mgtxmitframe(pxmitpriv);
+-      if (pmgntframe == NULL) {
++      if (!pmgntframe) {
+               return;
+       }
+@@ -3702,7 +3702,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
+                       pbss_network = (struct wlan_bssid_ex *)&pnetwork->network;
+                       p = rtw_get_ie(pbss_network->ies + _FIXED_IE_LENGTH_, WLAN_EID_HT_CAPABILITY, &len, pbss_network->ie_length - _FIXED_IE_LENGTH_);
+-                      if ((p == NULL) || (len == 0)) {/* non-HT */
++                      if (!p || len == 0) {/* non-HT */
+                               if (pbss_network->configuration.ds_config <= 0)
+                                       continue;
+@@ -3765,7 +3765,7 @@ unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr)
+                       return _SUCCESS;
+       psta = rtw_get_stainfo(pstapriv, addr);
+-      if (psta == NULL)
++      if (!psta)
+               return _SUCCESS;
+       if (initiator == 0) {/*  recipient */
+@@ -4637,13 +4637,13 @@ void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsi
+       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+       pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (pcmd_obj == NULL) {
++      if (!pcmd_obj) {
+               return;
+       }
+       cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
+       pevtcmd = rtw_zmalloc(cmdsz);
+-      if (pevtcmd == NULL) {
++      if (!pevtcmd) {
+               kfree(pcmd_obj);
+               return;
+       }
+@@ -4689,12 +4689,12 @@ void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int
+       struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
+       pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (pcmd_obj == NULL)
++      if (!pcmd_obj)
+               return;
+       cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
+       pevtcmd = rtw_zmalloc(cmdsz);
+-      if (pevtcmd == NULL) {
++      if (!pevtcmd) {
+               kfree(pcmd_obj);
+               return;
+       }
+@@ -5143,12 +5143,12 @@ void survey_timer_hdl(struct timer_list *t)
+               }
+               ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-              if (ph2c == NULL) {
++              if (!ph2c) {
+                       goto exit_survey_timer_hdl;
+               }
+               psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm));
+-              if (psurveyPara == NULL) {
++              if (!psurveyPara) {
+                       kfree(ph2c);
+                       goto exit_survey_timer_hdl;
+               }
+@@ -5777,7 +5777,7 @@ u8 chk_bmc_sleepq_cmd(struct adapter *padapter)
+       u8 res = _SUCCESS;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+@@ -5801,13 +5801,13 @@ u8 set_tx_beacon_cmd(struct adapter *padapter)
+       int len_diff = 0;
+       ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
+-      if (ph2c == NULL) {
++      if (!ph2c) {
+               res = _FAIL;
+               goto exit;
+       }
+       ptxBeacon_parm = rtw_zmalloc(sizeof(struct Tx_Beacon_param));
+-      if (ptxBeacon_parm == NULL) {
++      if (!ptxBeacon_parm) {
+               kfree(ph2c);
+               res = _FAIL;
+               goto exit;
+@@ -5867,7 +5867,7 @@ u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf)
+       void (*event_callback)(struct adapter *dev, u8 *pbuf);
+       struct evt_priv *pevt_priv = &(padapter->evtpriv);
+-      if (pbuf == NULL)
++      if (!pbuf)
+               goto _abort_event_;
+       peventbuf = (uint *)pbuf;
+diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c
+index b050bf62e3b94..ac731415f7332 100644
+--- a/drivers/staging/rtl8723bs/core/rtw_security.c
++++ b/drivers/staging/rtl8723bs/core/rtw_security.c
+@@ -51,7 +51,7 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
+       struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+       struct arc4_ctx *ctx = &psecuritypriv->xmit_arc4_ctx;
+-      if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
++      if (!((struct xmit_frame *)pxmitframe)->buf_addr)
+               return;
+       hw_hdr_offset = TXDESC_OFFSET;
+@@ -476,7 +476,7 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
+       struct arc4_ctx *ctx = &psecuritypriv->xmit_arc4_ctx;
+       u32 res = _SUCCESS;
+-      if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
++      if (!((struct xmit_frame *)pxmitframe)->buf_addr)
+               return _FAIL;
+       hw_hdr_offset = TXDESC_OFFSET;
+@@ -1043,7 +1043,7 @@ u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
+       u32 res = _SUCCESS;
+-      if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL)
++      if (!((struct xmit_frame *)pxmitframe)->buf_addr)
+               return _FAIL;
+       hw_hdr_offset = TXDESC_OFFSET;
+diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+index 448c4248ca4cf..20d05b4ee63e2 100644
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -391,7 +391,7 @@ void rtw_cfg80211_ibss_indicate_connect(struct adapter *padapter)
+               }
+               else
+               {
+-                      if (scanned == NULL) {
++                      if (!scanned) {
+                               rtw_warn_on(1);
+                               return;
+                       }
+@@ -432,7 +432,7 @@ void rtw_cfg80211_indicate_connect(struct adapter *padapter)
+               struct wlan_bssid_ex  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
+               struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
+-              if (scanned == NULL) {
++              if (!scanned) {
+                       rtw_warn_on(1);
+                       goto check_bss;
+               }
+@@ -551,10 +551,10 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+                       goto exit;
+       }
+-      if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL))
++      if (strcmp(param->u.crypt.alg, "none") == 0 && !psta)
+               goto exit;
+-      if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL))
++      if (strcmp(param->u.crypt.alg, "WEP") == 0 && !psta)
+       {
+               wep_key_idx = param->u.crypt.idx;
+               wep_key_len = param->u.crypt.key_len;
+@@ -907,7 +907,7 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
+                       }
+                       pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+-                      if (pbcmc_sta == NULL)
++                      if (!pbcmc_sta)
+                       {
+                               /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
+                       }
+@@ -947,7 +947,7 @@ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
+       param_len = sizeof(struct ieee_param) + params->key_len;
+       param = rtw_malloc(param_len);
+-      if (param == NULL)
++      if (!param)
+               return -1;
+       memset(param, 0, param_len);
+@@ -1098,7 +1098,7 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy,
+       }
+       psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
+-      if (psta == NULL) {
++      if (!psta) {
+               ret = -ENOENT;
+               goto exit;
+       }
+@@ -1327,7 +1327,7 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy
+       struct rtw_wdev_priv *pwdev_priv;
+       struct mlme_priv *pmlmepriv;
+-      if (ndev == NULL) {
++      if (!ndev) {
+               ret = -EINVAL;
+               goto exit;
+       }
+@@ -1571,7 +1571,7 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
+       u8 *pwpa, *pwpa2;
+       u8 null_addr[] = {0, 0, 0, 0, 0, 0};
+-      if (pie == NULL || !ielen) {
++      if (!pie || !ielen) {
+               /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
+               _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
+               goto exit;
+@@ -1583,7 +1583,7 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
+       }
+       buf = rtw_zmalloc(ielen);
+-      if (buf == NULL) {
++      if (!buf) {
+               ret =  -ENOMEM;
+               goto exit;
+       }
+@@ -1873,7 +1873,7 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
+                       wep_key_len = wep_key_len <= 5 ? 5 : 13;
+                       wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material);
+                       pwep = rtw_malloc(wep_total_len);
+-                      if (pwep == NULL) {
++                      if (!pwep) {
+                               ret = -ENOMEM;
+                               goto exit;
+                       }
+@@ -2708,7 +2708,7 @@ static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
+       struct adapter *padapter;
+       struct rtw_wdev_priv *pwdev_priv;
+-      if (ndev == NULL) {
++      if (!ndev) {
+               ret = -EINVAL;
+               goto exit;
+       }
+diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+index 295121c268bd4..f23ab3e103455 100644
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -153,7 +153,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
+               if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */
+                       psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
+-                      if (psta == NULL) {
++                      if (!psta) {
+                               /* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
+                       } else {
+                               /* Jeff: don't disable ieee8021x_blocked while clearing key */
+@@ -206,7 +206,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
+                       }
+                       pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+-                      if (pbcmc_sta == NULL) {
++                      if (!pbcmc_sta) {
+                               /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
+                       } else {
+                               /* Jeff: don't disable ieee8021x_blocked while clearing key */
+@@ -236,9 +236,9 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
+       int ret = 0;
+       u8 null_addr[] = {0, 0, 0, 0, 0, 0};
+-      if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
++      if (ielen > MAX_WPA_IE_LEN || !pie) {
+               _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
+-              if (pie == NULL)
++              if (!pie)
+                       return ret;
+               else
+                       return -EINVAL;
+@@ -246,7 +246,7 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
+       if (ielen) {
+               buf = rtw_zmalloc(ielen);
+-              if (buf == NULL) {
++              if (!buf) {
+                       ret =  -ENOMEM;
+                       goto exit;
+               }
+@@ -491,7 +491,7 @@ static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
+               return -EINVAL;
+       param = rtw_malloc(p->length);
+-      if (param == NULL)
++      if (!param)
+               return -ENOMEM;
+       if (copy_from_user(param, p->pointer, p->length)) {
+@@ -571,7 +571,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
+                       goto exit;
+       }
+-      if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
++      if (strcmp(param->u.crypt.alg, "none") == 0 && !psta) {
+               /* todo:clear default encryption keys */
+               psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
+@@ -583,7 +583,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
+       }
+-      if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
++      if (strcmp(param->u.crypt.alg, "WEP") == 0 && !psta) {
+               wep_key_idx = param->u.crypt.idx;
+               wep_key_len = param->u.crypt.key_len;
+@@ -1227,7 +1227,7 @@ static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
+               return -EINVAL;
+       param = rtw_malloc(p->length);
+-      if (param == NULL)
++      if (!param)
+               return -ENOMEM;
+       if (copy_from_user(param, p->pointer, p->length)) {
+diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+index 23f4f706f935c..279347be77c40 100644
+--- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c
++++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+@@ -488,7 +488,7 @@ void rtw_unregister_netdevs(struct dvobj_priv *dvobj)
+       padapter = dvobj->padapters;
+-      if (padapter == NULL)
++      if (!padapter)
+               return;
+       pnetdev = padapter->pnetdev;
+@@ -594,7 +594,7 @@ struct dvobj_priv *devobj_init(void)
+       struct dvobj_priv *pdvobj = NULL;
+       pdvobj = rtw_zmalloc(sizeof(*pdvobj));
+-      if (pdvobj == NULL)
++      if (!pdvobj)
+               return NULL;
+       mutex_init(&pdvobj->hw_init_mutex);
+-- 
+2.39.2
+
diff --git a/queue-5.15/staging-rtl8723bs-fix-key-store-index-handling.patch b/queue-5.15/staging-rtl8723bs-fix-key-store-index-handling.patch
new file mode 100644 (file)
index 0000000..6c338ff
--- /dev/null
@@ -0,0 +1,183 @@
+From d3b57f3361d05a5b0b03b863fd47307f0cec6ee7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Mar 2023 16:35:11 +0100
+Subject: staging: rtl8723bs: Fix key-store index handling
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 05cbcc415c9b8c8bc4f9a09f8e03610a89042f03 ]
+
+There are 2 issues with the key-store index handling
+
+1. The non WEP key stores can store keys with indexes 0 - BIP_MAX_KEYID,
+   this means that they should be an array with BIP_MAX_KEYID + 1
+   entries. But some of the arrays where just BIP_MAX_KEYID entries
+   big. While one other array was hardcoded to a size of 6 entries,
+   instead of using the BIP_MAX_KEYID define.
+
+2. The rtw_cfg80211_set_encryption() and wpa_set_encryption() functions
+   index check where checking that the passed in key-index would fit
+   inside both the WEP key store (which only has 4 entries) as well as
+   in the non WEP key stores. This breaks any attempts to set non WEP
+   keys with index 4 or 5.
+
+Issue 2. specifically breaks wifi connection with some access points
+which advertise PMF support. Without this fix connecting to these
+access points fails with the following wpa_supplicant messages:
+
+ nl80211: kernel reports: key addition failed
+ wlan0: WPA: Failed to configure IGTK to the driver
+ wlan0: RSN: Failed to configure IGTK
+ wlan0: CTRL-EVENT-DISCONNECTED bssid=... reason=1 locally_generated=1
+
+Fix 1. by using the right size for the key-stores. After this 2. can
+safely be fixed by checking the right max-index value depending on the
+used algorithm, fixing wifi not working with some PMF capable APs.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20230306153512.162104-1-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../staging/rtl8723bs/include/rtw_security.h  |  8 ++---
+ .../staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 26 ++++++++-------
+ .../staging/rtl8723bs/os_dep/ioctl_linux.c    | 33 ++++++++++---------
+ 3 files changed, 36 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/staging/rtl8723bs/include/rtw_security.h b/drivers/staging/rtl8723bs/include/rtw_security.h
+index a68b738584623..7587fa8885274 100644
+--- a/drivers/staging/rtl8723bs/include/rtw_security.h
++++ b/drivers/staging/rtl8723bs/include/rtw_security.h
+@@ -107,13 +107,13 @@ struct security_priv {
+       u32 dot118021XGrpPrivacy;       /*  This specify the privacy algthm. used for Grp key */
+       u32 dot118021XGrpKeyid;         /*  key id used for Grp Key (tx key index) */
+-      union Keytype   dot118021XGrpKey[BIP_MAX_KEYID];        /*  802.1x Group Key, for inx0 and inx1 */
+-      union Keytype   dot118021XGrptxmickey[BIP_MAX_KEYID];
+-      union Keytype   dot118021XGrprxmickey[BIP_MAX_KEYID];
++      union Keytype   dot118021XGrpKey[BIP_MAX_KEYID + 1];    /*  802.1x Group Key, for inx0 and inx1 */
++      union Keytype   dot118021XGrptxmickey[BIP_MAX_KEYID + 1];
++      union Keytype   dot118021XGrprxmickey[BIP_MAX_KEYID + 1];
+       union pn48              dot11Grptxpn;                   /*  PN48 used for Grp Key xmit. */
+       union pn48              dot11Grprxpn;                   /*  PN48 used for Grp Key recv. */
+       u32 dot11wBIPKeyid;                                             /*  key id used for BIP Key (tx key index) */
+-      union Keytype   dot11wBIPKey[6];                /*  BIP Key, for index4 and index5 */
++      union Keytype   dot11wBIPKey[BIP_MAX_KEYID + 1];        /*  BIP Key, for index4 and index5 */
+       union pn48              dot11wBIPtxpn;                  /*  PN48 used for Grp Key xmit. */
+       union pn48              dot11wBIPrxpn;                  /*  PN48 used for Grp Key recv. */
+diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+index b7a3f3df72723..b33424a9e83b7 100644
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -711,6 +711,7 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
+ {
+       int ret = 0;
++      u8 max_idx;
+       u32 wep_key_idx, wep_key_len;
+       struct adapter *padapter = rtw_netdev_priv(dev);
+       struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+@@ -724,26 +725,29 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
+               goto exit;
+       }
+-      if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+-          param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+-          param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+-              if (param->u.crypt.idx >= WEP_KEYS
+-                      || param->u.crypt.idx >= BIP_MAX_KEYID) {
+-                      ret = -EINVAL;
+-                      goto exit;
+-              }
+-      } else {
+-              {
++      if (param->sta_addr[0] != 0xff || param->sta_addr[1] != 0xff ||
++          param->sta_addr[2] != 0xff || param->sta_addr[3] != 0xff ||
++          param->sta_addr[4] != 0xff || param->sta_addr[5] != 0xff) {
+               ret = -EINVAL;
+               goto exit;
+       }
++
++      if (strcmp(param->u.crypt.alg, "WEP") == 0)
++              max_idx = WEP_KEYS - 1;
++      else
++              max_idx = BIP_MAX_KEYID;
++
++      if (param->u.crypt.idx > max_idx) {
++              netdev_err(dev, "Error crypt.idx %d > %d\n", param->u.crypt.idx, max_idx);
++              ret = -EINVAL;
++              goto exit;
+       }
+       if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+               wep_key_idx = param->u.crypt.idx;
+               wep_key_len = param->u.crypt.key_len;
+-              if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
++              if (wep_key_len <= 0) {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+index f23ab3e103455..0d2cb3e7ea4df 100644
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -60,6 +60,7 @@ static int wpa_set_auth_algs(struct net_device *dev, u32 value)
+ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
+ {
+       int ret = 0;
++      u8 max_idx;
+       u32 wep_key_idx, wep_key_len, wep_total_len;
+       struct ndis_802_11_wep   *pwep = NULL;
+       struct adapter *padapter = rtw_netdev_priv(dev);
+@@ -74,19 +75,22 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
+               goto exit;
+       }
+-      if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+-          param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+-          param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+-              if (param->u.crypt.idx >= WEP_KEYS ||
+-                  param->u.crypt.idx >= BIP_MAX_KEYID) {
+-                      ret = -EINVAL;
+-                      goto exit;
+-              }
+-      } else {
+-              {
+-                      ret = -EINVAL;
+-                      goto exit;
+-              }
++      if (param->sta_addr[0] != 0xff || param->sta_addr[1] != 0xff ||
++          param->sta_addr[2] != 0xff || param->sta_addr[3] != 0xff ||
++          param->sta_addr[4] != 0xff || param->sta_addr[5] != 0xff) {
++              ret = -EINVAL;
++              goto exit;
++      }
++
++      if (strcmp(param->u.crypt.alg, "WEP") == 0)
++              max_idx = WEP_KEYS - 1;
++      else
++              max_idx = BIP_MAX_KEYID;
++
++      if (param->u.crypt.idx > max_idx) {
++              netdev_err(dev, "Error crypt.idx %d > %d\n", param->u.crypt.idx, max_idx);
++              ret = -EINVAL;
++              goto exit;
+       }
+       if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+@@ -98,9 +102,6 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
+               wep_key_idx = param->u.crypt.idx;
+               wep_key_len = param->u.crypt.key_len;
+-              if (wep_key_idx > WEP_KEYS)
+-                      return -EINVAL;
+-
+               if (wep_key_len > 0) {
+                       wep_key_len = wep_key_len <= 5 ? 5 : 13;
+                       wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material);
+-- 
+2.39.2
+
diff --git a/queue-5.15/staging-rtl8723bs-fix-placement-of-braces.patch b/queue-5.15/staging-rtl8723bs-fix-placement-of-braces.patch
new file mode 100644 (file)
index 0000000..706e68b
--- /dev/null
@@ -0,0 +1,602 @@
+From d463310beae64ddc2445b2e280131864634e6c21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 28 May 2022 14:31:15 +0200
+Subject: staging: rtl8723bs: fix placement of braces
+
+From: Hannes Braun <hannesbraun@mail.de>
+
+[ Upstream commit a8b088d6d98dafddda9874f98ac2a7cefc51639b ]
+
+This patch should eliminate the following errors/warnings emitted by
+checkpatch.pl:
+- that open brace { should be on the previous line
+- else should follow close brace '}'
+- braces {} are not necessary for single statement blocks
+
+Signed-off-by: Hannes Braun <hannesbraun@mail.de>
+Link: https://lore.kernel.org/r/20220528123115.13024-1-hannesbraun@mail.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 05cbcc415c9b ("staging: rtl8723bs: Fix key-store index handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 223 +++++-------------
+ 1 file changed, 65 insertions(+), 158 deletions(-)
+
+diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+index 2404f7f84d82a..b7a3f3df72723 100644
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -366,9 +366,8 @@ void rtw_cfg80211_ibss_indicate_connect(struct adapter *padapter)
+       int freq = (int)cur_network->network.configuration.ds_config;
+       struct ieee80211_channel *chan;
+-      if (pwdev->iftype != NL80211_IFTYPE_ADHOC) {
++      if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
+               return;
+-      }
+       if (!rtw_cfg80211_check_bss(padapter)) {
+               struct wlan_bssid_ex  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
+@@ -544,9 +543,8 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+                       goto exit;
+               }
+-              if (wep_key_len > 0) {
++              if (wep_key_len > 0)
+                       wep_key_len = wep_key_len <= 5 ? 5 : 13;
+-              }
+               if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
+                       /* wep default key has not been set, so use this key index as default key. */
+@@ -582,9 +580,8 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+                               memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+                               psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+-                              if (param->u.crypt.key_len == 13) {
++                              if (param->u.crypt.key_len == 13)
+                                               psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+-                              }
+                       } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+                               psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+@@ -626,24 +623,16 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+       }
+-      if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) /*  psk/802_1x */
+-      {
+-              if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
+-              {
+-                      if (param->u.crypt.set_tx == 1) /* pairwise key */
+-                      {
++      if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /*  psk/802_1x */
++              if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
++                      if (param->u.crypt.set_tx == 1) { /* pairwise key */
+                               memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+-                              if (strcmp(param->u.crypt.alg, "WEP") == 0)
+-                              {
++                              if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+                                       psta->dot118021XPrivacy = _WEP40_;
+                                       if (param->u.crypt.key_len == 13)
+-                                      {
+                                               psta->dot118021XPrivacy = _WEP104_;
+-                                      }
+-                              }
+-                              else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
+-                              {
++                              } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+                                       psta->dot118021XPrivacy = _TKIP_;
+                                       /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
+@@ -653,14 +642,10 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+                                       psecuritypriv->busetkipkey = true;
+-                              }
+-                              else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
+-                              {
++                              } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+                                       psta->dot118021XPrivacy = _AES_;
+-                              }
+-                              else
+-                              {
++                              } else {
+                                       psta->dot118021XPrivacy = _NO_PRIVACY_;
+                               }
+@@ -670,21 +655,14 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+                               psta->bpairwise_key_installed = true;
+-                      }
+-                      else/* group key??? */
+-                      {
+-                              if (strcmp(param->u.crypt.alg, "WEP") == 0)
+-                              {
++                      } else { /* group key??? */
++                              if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+                                       memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+                                       psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+                                       if (param->u.crypt.key_len == 13)
+-                                      {
+                                               psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+-                                      }
+-                              }
+-                              else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
+-                              {
++                              } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+                                       psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+                                       memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+@@ -696,15 +674,11 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+                                       psecuritypriv->busetkipkey = true;
+-                              }
+-                              else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
+-                              {
++                              } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+                                       psecuritypriv->dot118021XGrpPrivacy = _AES_;
+                                       memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+-                              }
+-                              else
+-                              {
++                              } else {
+                                       psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+                               }
+@@ -717,8 +691,7 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+                               rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
+                               pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+-                              if (pbcmc_sta)
+-                              {
++                              if (pbcmc_sta) {
+                                       pbcmc_sta->ieee8021x_blocked = false;
+                                       pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
+                               }
+@@ -746,20 +719,16 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
+       param->u.crypt.err = 0;
+       param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+-      if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
+-      {
++      if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {
+               ret =  -EINVAL;
+               goto exit;
+       }
+       if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+           param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+-          param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
+-      {
++          param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+               if (param->u.crypt.idx >= WEP_KEYS
+-                      || param->u.crypt.idx >= BIP_MAX_KEYID
+-              )
+-              {
++                      || param->u.crypt.idx >= BIP_MAX_KEYID) {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+@@ -770,19 +739,16 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
+       }
+       }
+-      if (strcmp(param->u.crypt.alg, "WEP") == 0)
+-      {
++      if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+               wep_key_idx = param->u.crypt.idx;
+               wep_key_len = param->u.crypt.key_len;
+-              if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0))
+-              {
++              if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+-              if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
+-              {
++              if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
+                       /* wep default key has not been set, so use this key index as default key. */
+                       wep_key_len = wep_key_len <= 5 ? 5 : 13;
+@@ -791,8 +757,7 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
+                       psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
+                       psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+-                      if (wep_key_len == 13)
+-                      {
++                      if (wep_key_len == 13) {
+                               psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
+                               psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+                       }
+@@ -809,13 +774,11 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
+               goto exit;
+       }
+-      if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) /*  802_1x */
+-      {
++      if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /*  802_1x */
+               struct sta_info *psta, *pbcmc_sta;
+               struct sta_priv *pstapriv = &padapter->stapriv;
+-              if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) /* sta mode */
+-              {
++              if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */
+                       psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
+                       if (psta) {
+                               /* Jeff: don't disable ieee8021x_blocked while clearing key */
+@@ -824,18 +787,15 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
+                               if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
+-                                              (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
+-                              {
++                                              (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled)) {
+                                       psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
+                               }
+-                              if (param->u.crypt.set_tx == 1)/* pairwise key */
+-                              {
++                              if (param->u.crypt.set_tx == 1) { /* pairwise key */
+                                       memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+-                                      if (strcmp(param->u.crypt.alg, "TKIP") == 0)/* set mic key */
+-                                      {
++                                      if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
+                                               /* DEBUG_ERR(("\nset key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
+                                               memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
+                                               memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
+@@ -845,11 +805,8 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
+                                       }
+                                       rtw_setstakey_cmd(padapter, psta, true, true);
+-                              }
+-                              else/* group key */
+-                              {
+-                                      if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
+-                                      {
++                              } else { /* group key */
++                                      if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
+                                               memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+                                               memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
+                                               memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
+@@ -857,9 +814,7 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
+                                               padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
+                                               rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, true);
+-                                      }
+-                                      else if (strcmp(param->u.crypt.alg, "BIP") == 0)
+-                                      {
++                                      } else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
+                                               /* save the IGTK key, length 16 bytes */
+                                               memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+                                               /*
+@@ -873,25 +828,19 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
+                       }
+                       pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+-                      if (!pbcmc_sta)
+-                      {
++                      if (!pbcmc_sta) {
+                               /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
+-                      }
+-                      else
+-                      {
++                      } else {
+                               /* Jeff: don't disable ieee8021x_blocked while clearing key */
+                               if (strcmp(param->u.crypt.alg, "none") != 0)
+                                       pbcmc_sta->ieee8021x_blocked = false;
+                               if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
+-                                              (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
+-                              {
++                                              (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled)) {
+                                       pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
+                               }
+                       }
+-              }
+-              else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) /* adhoc mode */
+-              {
++              } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */
+               }
+       }
+@@ -949,39 +898,29 @@ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
+       if (!mac_addr || is_broadcast_ether_addr(mac_addr))
+-      {
+               param->u.crypt.set_tx = 0; /* for wpa/wpa2 group key */
+-      } else {
++      else
+               param->u.crypt.set_tx = 1; /* for wpa/wpa2 pairwise key */
+-      }
+       param->u.crypt.idx = key_index;
+       if (params->seq_len && params->seq)
+-      {
+               memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
+-      }
+-      if (params->key_len && params->key)
+-      {
++      if (params->key_len && params->key) {
+               param->u.crypt.key_len = params->key_len;
+               memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
+       }
+-      if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
+-      {
++      if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
+               ret =  rtw_cfg80211_set_encryption(ndev, param, param_len);
+-      }
+-      else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+-      {
++      } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
+               if (mac_addr)
+                       memcpy(param->sta_addr, (void *)mac_addr, ETH_ALEN);
+               ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
+-      }
+-        else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true
+-                || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)
+-        {
++      } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true
++                || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
+                 ret =  rtw_cfg80211_set_encryption(ndev, param, param_len);
+         }
+@@ -1007,8 +946,7 @@ static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
+       struct adapter *padapter = rtw_netdev_priv(ndev);
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+-      if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
+-      {
++      if (key_index == psecuritypriv->dot11PrivacyKeyIndex) {
+               /* clear the flag of wep default key set. */
+               psecuritypriv->bWepDefaultKeyIdxSet = 0;
+       }
+@@ -1024,16 +962,14 @@ static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
+       struct adapter *padapter = rtw_netdev_priv(ndev);
+       struct security_priv *psecuritypriv = &padapter->securitypriv;
+-      if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) /* set wep default key */
+-      {
++      if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) { /* set wep default key */
+               psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
+               psecuritypriv->dot11PrivacyKeyIndex = key_index;
+               psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
+               psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+-              if (psecuritypriv->dot11DefKeylen[key_index] == 13)
+-              {
++              if (psecuritypriv->dot11DefKeylen[key_index] == 13) {
+                       psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
+                       psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+               }
+@@ -1071,9 +1007,7 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy,
+       /* for infra./P2PClient mode */
+       if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
+-              && check_fwstate(pmlmepriv, _FW_LINKED)
+-      )
+-      {
++              && check_fwstate(pmlmepriv, _FW_LINKED)) {
+               struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
+               if (memcmp((u8 *)mac, cur_network->network.mac_address, ETH_ALEN)) {
+@@ -1099,9 +1033,7 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy,
+       if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
+  || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
+  || check_fwstate(pmlmepriv, WIFI_AP_STATE))
+-              && check_fwstate(pmlmepriv, _FW_LINKED)
+-      )
+-      {
++              && check_fwstate(pmlmepriv, _FW_LINKED)) {
+               /* TODO: should acquire station info... */
+       }
+@@ -1121,8 +1053,7 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
+       struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+       int ret = 0;
+-      if (adapter_to_dvobj(padapter)->processing_dev_remove == true)
+-      {
++      if (adapter_to_dvobj(padapter)->processing_dev_remove == true) {
+               ret = -EPERM;
+               goto exit;
+       }
+@@ -1141,8 +1072,7 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
+       old_type = rtw_wdev->iftype;
+-      if (old_type != type)
+-      {
++      if (old_type != type) {
+               pmlmeext->action_public_rxseq = 0xffff;
+               pmlmeext->action_public_dialog_token = 0xff;
+       }
+@@ -1164,8 +1094,7 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
+       rtw_wdev->iftype = type;
+-      if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == false)
+-      {
++      if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == false) {
+               rtw_wdev->iftype = old_type;
+               ret = -EPERM;
+               goto exit;
+@@ -1230,9 +1159,7 @@ void rtw_cfg80211_surveydone_event_callback(struct adapter *padapter)
+               /* report network only if the current channel set contains the channel to which this network belongs */
+               if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.configuration.ds_config) >= 0
+-                      && true == rtw_validate_ssid(&(pnetwork->network.ssid))
+-              )
+-              {
++                      && true == rtw_validate_ssid(&(pnetwork->network.ssid))) {
+                       /* ev =translate_scan(padapter, a, pnetwork, ev, stop); */
+                       rtw_cfg80211_inform_bss(padapter, pnetwork);
+               }
+@@ -1249,13 +1176,10 @@ static int rtw_cfg80211_set_probe_req_wpsp2pie(struct adapter *padapter, char *b
+       u8 *wps_ie;
+       struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+-      if (len > 0)
+-      {
++      if (len > 0) {
+               wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
+-              if (wps_ie)
+-              {
+-                      if (pmlmepriv->wps_probe_req_ie)
+-                      {
++              if (wps_ie) {
++                      if (pmlmepriv->wps_probe_req_ie) {
+                               pmlmepriv->wps_probe_req_ie_len = 0;
+                               kfree(pmlmepriv->wps_probe_req_ie);
+                               pmlmepriv->wps_probe_req_ie = NULL;
+@@ -1307,10 +1231,8 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy
+       pwdev_priv->scan_request = request;
+       spin_unlock_bh(&pwdev_priv->scan_req_lock);
+-      if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
+-      {
+-              if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true)
+-              {
++      if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
++              if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) {
+                       need_indicate_scan_done = true;
+                       goto check_need_indicate_scan_done;
+               }
+@@ -1333,15 +1255,13 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy
+               goto check_need_indicate_scan_done;
+       }
+-      if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true)
+-      {
++      if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) {
+               static unsigned long lastscantime = 0;
+               unsigned long passtime;
+               passtime = jiffies_to_msecs(jiffies - lastscantime);
+               lastscantime = jiffies;
+-              if (passtime > 12000)
+-              {
++              if (passtime > 12000) {
+                       need_indicate_scan_done = true;
+                       goto check_need_indicate_scan_done;
+               }
+@@ -1380,9 +1300,7 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy
+       } else if (request->n_channels <= 4) {
+               for (j = request->n_channels - 1; j >= 0; j--)
+                       for (i = 0; i < survey_times; i++)
+-              {
+                       memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
+-              }
+               _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
+       } else {
+               _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
+@@ -1391,14 +1309,11 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy
+       if (_status == false)
+-      {
+               ret = -1;
+-      }
+ check_need_indicate_scan_done:
+       kfree(ssid);
+-      if (need_indicate_scan_done)
+-      {
++      if (need_indicate_scan_done) {
+               rtw_cfg80211_surveydone_event_callback(padapter);
+               rtw_cfg80211_indicate_scan_done(padapter, false);
+       }
+@@ -1424,9 +1339,7 @@ static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32
+       if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
+-      {
+               psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
+-      }
+       return 0;
+@@ -1585,8 +1498,7 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
+       if (pairwise_cipher == 0)
+               pairwise_cipher = WPA_CIPHER_NONE;
+-      switch (group_cipher)
+-      {
++      switch (group_cipher) {
+               case WPA_CIPHER_NONE:
+                       padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
+                       padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
+@@ -1609,8 +1521,7 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
+                       break;
+       }
+-      switch (pairwise_cipher)
+-      {
++      switch (pairwise_cipher) {
+               case WPA_CIPHER_NONE:
+                       padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
+                       padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
+@@ -1731,8 +1642,7 @@ static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
+               rtw_wdev->iftype = NL80211_IFTYPE_STATION;
+-              if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) == false)
+-              {
++              if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) == false) {
+                       rtw_wdev->iftype = old_type;
+                       ret = -EPERM;
+                       goto leave_ibss;
+@@ -1792,9 +1702,8 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
+               ret = -EBUSY;
+               goto exit;
+       }
+-      if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
++      if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
+               rtw_scan_abort(padapter);
+-      }
+       psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
+       psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
+@@ -2287,9 +2196,8 @@ static int rtw_cfg80211_add_monitor_if(struct adapter *padapter, char *name, str
+       mon_ndev->ieee80211_ptr = mon_wdev;
+       ret = cfg80211_register_netdevice(mon_ndev);
+-      if (ret) {
++      if (ret)
+               goto out;
+-      }
+       *ndev = pwdev_priv->pmon_ndev = mon_ndev;
+       memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
+@@ -2402,11 +2310,10 @@ static int rtw_add_beacon(struct adapter *adapter, const u8 *head, size_t head_l
+       rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, WLAN_EID_VENDOR_SPECIFIC, P2P_OUI, 4);
+       rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, WLAN_EID_VENDOR_SPECIFIC, WFD_OUI, 4);
+-      if (rtw_check_beacon_data(adapter, pbuf,  len) == _SUCCESS) {
++      if (rtw_check_beacon_data(adapter, pbuf,  len) == _SUCCESS)
+               ret = 0;
+-      } else {
++      else
+               ret = -EINVAL;
+-      }
+       kfree(pbuf);
+-- 
+2.39.2
+
diff --git a/queue-5.15/staging-rtl8723bs-placing-opening-braces-in-previous.patch b/queue-5.15/staging-rtl8723bs-placing-opening-braces-in-previous.patch
new file mode 100644 (file)
index 0000000..1725601
--- /dev/null
@@ -0,0 +1,261 @@
+From ae2b09751e9377de8a482d56e363f92cccb01d96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jan 2022 09:14:54 +0530
+Subject: Staging: rtl8723bs: Placing opening { braces in previous line
+
+From: Jagath Jog J <jagathjog1996@gmail.com>
+
+[ Upstream commit 1d7280898f683ca824fc5eab5c486a583a81473b ]
+
+Fix following checkpatch.pl error by placing opening {
+braces in previous line
+ERROR: that open brace { should be on the previous line
+
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Jagath Jog J <jagathjog1996@gmail.com>
+Link: https://lore.kernel.org/r/20220124034456.8665-2-jagathjog1996@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 05cbcc415c9b ("staging: rtl8723bs: Fix key-store index handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 98 ++++++-------------
+ 1 file changed, 32 insertions(+), 66 deletions(-)
+
+diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+index 20d05b4ee63e2..2404f7f84d82a 100644
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+@@ -113,13 +113,10 @@ static struct ieee80211_supported_band *rtw_spt_band_alloc(
+       struct ieee80211_supported_band *spt_band = NULL;
+       int n_channels, n_bitrates;
+-      if (band == NL80211_BAND_2GHZ)
+-      {
++      if (band == NL80211_BAND_2GHZ) {
+               n_channels = RTW_2G_CHANNELS_NUM;
+               n_bitrates = RTW_G_RATES_NUM;
+-      }
+-      else
+-      {
++      } else {
+               goto exit;
+       }
+@@ -135,8 +132,7 @@ static struct ieee80211_supported_band *rtw_spt_band_alloc(
+       spt_band->n_channels = n_channels;
+       spt_band->n_bitrates = n_bitrates;
+-      if (band == NL80211_BAND_2GHZ)
+-      {
++      if (band == NL80211_BAND_2GHZ) {
+               rtw_2g_channels_init(spt_band->channels);
+               rtw_2g_rates_init(spt_band->bitrates);
+       }
+@@ -235,8 +231,7 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(struct adapter *padapter, struct wl
+       {
+               u16 wapi_len = 0;
+-              if (rtw_get_wapi_ie(pnetwork->network.ies, pnetwork->network.ie_length, NULL, &wapi_len) > 0)
+-              {
++              if (rtw_get_wapi_ie(pnetwork->network.ies, pnetwork->network.ie_length, NULL, &wapi_len) > 0) {
+                       if (wapi_len > 0)
+                               goto exit;
+               }
+@@ -244,8 +239,7 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(struct adapter *padapter, struct wl
+       /* To reduce PBC Overlap rate */
+       /* spin_lock_bh(&pwdev_priv->scan_req_lock); */
+-      if (adapter_wdev_data(padapter)->scan_request)
+-      {
++      if (adapter_wdev_data(padapter)->scan_request) {
+               u8 *psr = NULL, sr = 0;
+               struct ndis_802_11_ssid *pssid = &pnetwork->network.ssid;
+               struct cfg80211_scan_request *request = adapter_wdev_data(padapter)->scan_request;
+@@ -258,14 +252,12 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(struct adapter *padapter, struct wl
+               if (wpsie && wpsielen > 0)
+                       psr = rtw_get_wps_attr_content(wpsie,  wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
+-              if (sr != 0)
+-              {
+-                      if (request->n_ssids == 1 && request->n_channels == 1) /*  it means under processing WPS */
+-                      {
++              if (sr != 0) {
++                      /* it means under processing WPS */
++                      if (request->n_ssids == 1 && request->n_channels == 1) {
+                               if (ssids[0].ssid_len != 0 &&
+                                   (pssid->ssid_length != ssids[0].ssid_len ||
+-                                   memcmp(pssid->ssid, ssids[0].ssid, ssids[0].ssid_len)))
+-                              {
++                                   memcmp(pssid->ssid, ssids[0].ssid, ssids[0].ssid_len))) {
+                                       if (psr)
+                                               *psr = 0; /* clear sr */
+                               }
+@@ -374,8 +366,7 @@ void rtw_cfg80211_ibss_indicate_connect(struct adapter *padapter)
+       int freq = (int)cur_network->network.configuration.ds_config;
+       struct ieee80211_channel *chan;
+-      if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
+-      {
++      if (pwdev->iftype != NL80211_IFTYPE_ADHOC) {
+               return;
+       }
+@@ -383,14 +374,11 @@ void rtw_cfg80211_ibss_indicate_connect(struct adapter *padapter)
+               struct wlan_bssid_ex  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
+               struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
+-              if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)
+-              {
++              if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
+                       memcpy(&cur_network->network, pnetwork, sizeof(struct wlan_bssid_ex));
+                       rtw_cfg80211_inform_bss(padapter, cur_network);
+-              }
+-              else
+-              {
++              } else {
+                       if (!scanned) {
+                               rtw_warn_on(1);
+                               return;
+@@ -473,9 +461,7 @@ void rtw_cfg80211_indicate_connect(struct adapter *padapter)
+               roam_info.resp_ie_len =
+                       pmlmepriv->assoc_rsp_len-sizeof(struct ieee80211_hdr_3addr)-6;
+               cfg80211_roamed(padapter->pnetdev, &roam_info, GFP_ATOMIC);
+-      }
+-      else
+-      {
++      } else {
+               cfg80211_connect_result(padapter->pnetdev, cur_network->network.mac_address
+                       , pmlmepriv->assoc_req+sizeof(struct ieee80211_hdr_3addr)+2
+                       , pmlmepriv->assoc_req_len-sizeof(struct ieee80211_hdr_3addr)-2
+@@ -527,24 +513,19 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+       param->u.crypt.err = 0;
+       param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+-      if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len)
+-      {
++      if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len) {
+               ret =  -EINVAL;
+               goto exit;
+       }
+       if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+           param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+-          param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
+-      {
+-              if (param->u.crypt.idx >= WEP_KEYS)
+-              {
++          param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
++              if (param->u.crypt.idx >= WEP_KEYS) {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+-      }
+-      else
+-      {
++      } else {
+               psta = rtw_get_stainfo(pstapriv, param->sta_addr);
+               if (!psta)
+                       /* ret = -EINVAL; */
+@@ -554,24 +535,20 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+       if (strcmp(param->u.crypt.alg, "none") == 0 && !psta)
+               goto exit;
+-      if (strcmp(param->u.crypt.alg, "WEP") == 0 && !psta)
+-      {
++      if (strcmp(param->u.crypt.alg, "WEP") == 0 && !psta) {
+               wep_key_idx = param->u.crypt.idx;
+               wep_key_len = param->u.crypt.key_len;
+-              if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0))
+-              {
++              if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
+                       ret = -EINVAL;
+                       goto exit;
+               }
+-              if (wep_key_len > 0)
+-              {
++              if (wep_key_len > 0) {
+                       wep_key_len = wep_key_len <= 5 ? 5 : 13;
+               }
+-              if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
+-              {
++              if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
+                       /* wep default key has not been set, so use this key index as default key. */
+                       psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
+@@ -579,8 +556,7 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+                       psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
+                       psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+-                      if (wep_key_len == 13)
+-                      {
++                      if (wep_key_len == 13) {
+                               psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
+                               psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+                       }
+@@ -598,24 +574,19 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+       }
+-
+-      if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) /* group key */
+-      {
+-              if (param->u.crypt.set_tx == 0) /* group key */
+-              {
+-                      if (strcmp(param->u.crypt.alg, "WEP") == 0)
+-                      {
++      /* group key */
++      if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
++              /* group key */
++              if (param->u.crypt.set_tx == 0) {
++                      if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+                               memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+                               psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
+-                              if (param->u.crypt.key_len == 13)
+-                              {
++                              if (param->u.crypt.key_len == 13) {
+                                               psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
+                               }
+-                      }
+-                      else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
+-                      {
++                      } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+                               psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
+                               memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+@@ -627,15 +598,11 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+                               psecuritypriv->busetkipkey = true;
+-                      }
+-                      else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
+-                      {
++                      } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+                               psecuritypriv->dot118021XGrpPrivacy = _AES_;
+                               memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
+-                      }
+-                      else
+-                      {
++                      } else {
+                               psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
+                       }
+@@ -648,8 +615,7 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
+                       rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
+                       pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
+-                      if (pbcmc_sta)
+-                      {
++                      if (pbcmc_sta) {
+                               pbcmc_sta->ieee8021x_blocked = false;
+                               pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
+                       }
+-- 
+2.39.2
+
diff --git a/queue-5.15/tpm-eventlog-don-t-abort-tpm_read_log-on-faulty-acpi.patch b/queue-5.15/tpm-eventlog-don-t-abort-tpm_read_log-on-faulty-acpi.patch
new file mode 100644 (file)
index 0000000..ae70678
--- /dev/null
@@ -0,0 +1,73 @@
+From b8e38b713d9cf62b761c2af3dcef58380152214c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 10:25:52 +0100
+Subject: tpm/eventlog: Don't abort tpm_read_log on faulty ACPI address
+
+From: Morten Linderud <morten@linderud.pw>
+
+[ Upstream commit 80a6c216b16d7f5c584d2148c2e4345ea4eb06ce ]
+
+tpm_read_log_acpi() should return -ENODEV when no eventlog from the ACPI
+table is found. If the firmware vendor includes an invalid log address
+we are unable to map from the ACPI memory and tpm_read_log() returns -EIO
+which would abort discovery of the eventlog.
+
+Change the return value from -EIO to -ENODEV when acpi_os_map_iomem()
+fails to map the event log.
+
+The following hardware was used to test this issue:
+    Framework Laptop (Pre-production)
+    BIOS: INSYDE Corp, Revision: 3.2
+    TPM Device: NTC, Firmware Revision: 7.2
+
+Dump of the faulty ACPI TPM2 table:
+    [000h 0000   4]                    Signature : "TPM2"    [Trusted Platform Module hardware interface Table]
+    [004h 0004   4]                 Table Length : 0000004C
+    [008h 0008   1]                     Revision : 04
+    [009h 0009   1]                     Checksum : 2B
+    [00Ah 0010   6]                       Oem ID : "INSYDE"
+    [010h 0016   8]                 Oem Table ID : "TGL-ULT"
+    [018h 0024   4]                 Oem Revision : 00000002
+    [01Ch 0028   4]              Asl Compiler ID : "ACPI"
+    [020h 0032   4]        Asl Compiler Revision : 00040000
+
+    [024h 0036   2]               Platform Class : 0000
+    [026h 0038   2]                     Reserved : 0000
+    [028h 0040   8]              Control Address : 0000000000000000
+    [030h 0048   4]                 Start Method : 06 [Memory Mapped I/O]
+
+    [034h 0052  12]            Method Parameters : 00 00 00 00 00 00 00 00 00 00 00 00
+    [040h 0064   4]           Minimum Log Length : 00010000
+    [044h 0068   8]                  Log Address : 000000004053D000
+
+Fixes: 0cf577a03f21 ("tpm: Fix handling of missing event log")
+Tested-by: Erkki Eilonen <erkki@bearmetal.eu>
+Signed-off-by: Morten Linderud <morten@linderud.pw>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/tpm/eventlog/acpi.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
+index 0913d3eb8d518..cd266021d0103 100644
+--- a/drivers/char/tpm/eventlog/acpi.c
++++ b/drivers/char/tpm/eventlog/acpi.c
+@@ -143,8 +143,12 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
+       ret = -EIO;
+       virt = acpi_os_map_iomem(start, len);
+-      if (!virt)
++      if (!virt) {
++              dev_warn(&chip->dev, "%s: Failed to map ACPI memory\n", __func__);
++              /* try EFI log next */
++              ret = -ENODEV;
+               goto err;
++      }
+       memcpy_fromio(log->bios_event_log, virt, len);
+-- 
+2.39.2
+
diff --git a/queue-5.15/watch_queue-fix-ioc_watch_queue_set_size-alloc-error.patch b/queue-5.15/watch_queue-fix-ioc_watch_queue_set_size-alloc-error.patch
new file mode 100644 (file)
index 0000000..e02cc05
--- /dev/null
@@ -0,0 +1,39 @@
+From f64f2da35cfb3521462ecec2efd2c67ad4b09381 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 16:21:06 +0100
+Subject: watch_queue: fix IOC_WATCH_QUEUE_SET_SIZE alloc error paths
+
+From: David Disseldorp <ddiss@suse.de>
+
+[ Upstream commit 03e1d60e177eedbd302b77af4ea5e21b5a7ade31 ]
+
+The watch_queue_set_size() allocation error paths return the ret value
+set via the prior pipe_resize_ring() call, which will always be zero.
+
+As a result, IOC_WATCH_QUEUE_SET_SIZE callers such as "keyctl watch"
+fail to detect kernel wqueue->notes allocation failures and proceed to
+KEYCTL_WATCH_KEY, with any notifications subsequently lost.
+
+Fixes: c73be61cede58 ("pipe: Add general notification queue support")
+Signed-off-by: David Disseldorp <ddiss@suse.de>
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/watch_queue.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
+index 1059ef6c3711a..54cbaa9711398 100644
+--- a/kernel/watch_queue.c
++++ b/kernel/watch_queue.c
+@@ -274,6 +274,7 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
+       if (ret < 0)
+               goto error;
++      ret = -ENOMEM;
+       pages = kcalloc(sizeof(struct page *), nr_pages, GFP_KERNEL);
+       if (!pages)
+               goto error;
+-- 
+2.39.2
+
diff --git a/queue-5.15/xfs-fallocate-should-call-file_modified.patch b/queue-5.15/xfs-fallocate-should-call-file_modified.patch
new file mode 100644 (file)
index 0000000..b664793
--- /dev/null
@@ -0,0 +1,71 @@
+From e5772e2e8f1bfd5feeb4caa9e37d2a6600aa82de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:14 -0800
+Subject: xfs: fallocate() should call file_modified()
+
+From: Dave Chinner <dchinner@redhat.com>
+
+commit fbe7e520036583a783b13ff9744e35c2a329d9a4 upsream.
+
+In XFS, we always update the inode change and modification time when
+any fallocate() operation succeeds.  Furthermore, as various
+fallocate modes can change the file contents (extending EOF,
+punching holes, zeroing things, shifting extents), we should drop
+file privileges like suid just like we do for a regular write().
+There's already a VFS helper that figures all this out for us, so
+use that.
+
+The net effect of this is that we no longer drop suid/sgid if the
+caller is root, but we also now drop file capabilities.
+
+We also move the xfs_update_prealloc_flags() function so that it now
+is only called by the scope that needs to set the the prealloc flag.
+
+Based on a patch from Darrick Wong.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/xfs_file.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
+index 752b676c92e3f..020e0a412287a 100644
+--- a/fs/xfs/xfs_file.c
++++ b/fs/xfs/xfs_file.c
+@@ -954,6 +954,10 @@ xfs_file_fallocate(
+                       goto out_unlock;
+       }
++      error = file_modified(file);
++      if (error)
++              goto out_unlock;
++
+       if (mode & FALLOC_FL_PUNCH_HOLE) {
+               error = xfs_free_file_space(ip, offset, len);
+               if (error)
+@@ -1055,11 +1059,12 @@ xfs_file_fallocate(
+                       if (error)
+                               goto out_unlock;
+               }
+-      }
+-      error = xfs_update_prealloc_flags(ip, flags);
+-      if (error)
+-              goto out_unlock;
++              error = xfs_update_prealloc_flags(ip, XFS_PREALLOC_SET);
++              if (error)
++                      goto out_unlock;
++
++      }
+       /* Change file size if needed */
+       if (new_size) {
+-- 
+2.39.2
+
diff --git a/queue-5.15/xfs-remove-xfs_prealloc_sync.patch b/queue-5.15/xfs-remove-xfs_prealloc_sync.patch
new file mode 100644 (file)
index 0000000..4e06c07
--- /dev/null
@@ -0,0 +1,89 @@
+From 562ab7efef31bd4458c90e038a0d630232e89b16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:13 -0800
+Subject: xfs: remove XFS_PREALLOC_SYNC
+
+From: Dave Chinner <dchinner@redhat.com>
+
+commit 472c6e46f589c26057596dcba160712a5b3e02c5 upstream.
+
+[partial backport for dependency -
+ xfs_ioc_space() still uses XFS_PREALLOC_SYNC]
+
+Callers can acheive the same thing by calling xfs_log_force_inode()
+after making their modifications. There is no need for
+xfs_update_prealloc_flags() to do this.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/xfs_file.c | 13 +++++++------
+ fs/xfs/xfs_pnfs.c |  6 ++++--
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
+index 240eb932c014b..752b676c92e3f 100644
+--- a/fs/xfs/xfs_file.c
++++ b/fs/xfs/xfs_file.c
+@@ -95,8 +95,6 @@ xfs_update_prealloc_flags(
+               ip->i_diflags &= ~XFS_DIFLAG_PREALLOC;
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+-      if (flags & XFS_PREALLOC_SYNC)
+-              xfs_trans_set_sync(tp);
+       return xfs_trans_commit(tp);
+ }
+@@ -1059,9 +1057,6 @@ xfs_file_fallocate(
+               }
+       }
+-      if (file->f_flags & O_DSYNC)
+-              flags |= XFS_PREALLOC_SYNC;
+-
+       error = xfs_update_prealloc_flags(ip, flags);
+       if (error)
+               goto out_unlock;
+@@ -1084,8 +1079,14 @@ xfs_file_fallocate(
+        * leave shifted extents past EOF and hence losing access to
+        * the data that is contained within them.
+        */
+-      if (do_file_insert)
++      if (do_file_insert) {
+               error = xfs_insert_file_space(ip, offset, len);
++              if (error)
++                      goto out_unlock;
++      }
++
++      if (file->f_flags & O_DSYNC)
++              error = xfs_log_force_inode(ip);
+ out_unlock:
+       xfs_iunlock(ip, iolock);
+diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
+index 8865f7d4404ae..3a82a13d880c2 100644
+--- a/fs/xfs/xfs_pnfs.c
++++ b/fs/xfs/xfs_pnfs.c
+@@ -164,10 +164,12 @@ xfs_fs_map_blocks(
+                * that the blocks allocated and handed out to the client are
+                * guaranteed to be present even after a server crash.
+                */
+-              error = xfs_update_prealloc_flags(ip,
+-                              XFS_PREALLOC_SET | XFS_PREALLOC_SYNC);
++              error = xfs_update_prealloc_flags(ip, XFS_PREALLOC_SET);
++              if (!error)
++                      error = xfs_log_force_inode(ip);
+               if (error)
+                       goto out_unlock;
++
+       } else {
+               xfs_iunlock(ip, lock_flags);
+       }
+-- 
+2.39.2
+
diff --git a/queue-5.15/xfs-set-prealloc-flag-in-xfs_alloc_file_space.patch b/queue-5.15/xfs-set-prealloc-flag-in-xfs_alloc_file_space.patch
new file mode 100644 (file)
index 0000000..ca71a08
--- /dev/null
@@ -0,0 +1,95 @@
+From 4eafcd9d73d2055b99e9547db132f08df7458c9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:15 -0800
+Subject: xfs: set prealloc flag in xfs_alloc_file_space()
+
+From: Dave Chinner <dchinner@redhat.com>
+
+commit 0b02c8c0d75a738c98c35f02efb36217c170d78c upsream.
+
+Now that we only call xfs_update_prealloc_flags() from
+xfs_file_fallocate() in the case where we need to set the
+preallocation flag, do this in xfs_alloc_file_space() where we
+already have the inode joined into a transaction and get
+rid of the call to xfs_update_prealloc_flags() from the fallocate
+code.
+
+This also means that we now correctly avoid setting the
+XFS_DIFLAG_PREALLOC flag when xfs_is_always_cow_inode() is true, as
+these inodes will never have preallocated extents.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/xfs_bmap_util.c | 9 +++------
+ fs/xfs/xfs_file.c      | 8 --------
+ 2 files changed, 3 insertions(+), 14 deletions(-)
+
+diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
+index 73a36b7be3bd1..fd2ad6a3019ca 100644
+--- a/fs/xfs/xfs_bmap_util.c
++++ b/fs/xfs/xfs_bmap_util.c
+@@ -851,9 +851,6 @@ xfs_alloc_file_space(
+                       rblocks = 0;
+               }
+-              /*
+-               * Allocate and setup the transaction.
+-               */
+               error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_write,
+                               dblocks, rblocks, false, &tp);
+               if (error)
+@@ -870,9 +867,9 @@ xfs_alloc_file_space(
+               if (error)
+                       goto error;
+-              /*
+-               * Complete the transaction
+-               */
++              ip->i_diflags |= XFS_DIFLAG_PREALLOC;
++              xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
++
+               error = xfs_trans_commit(tp);
+               xfs_iunlock(ip, XFS_ILOCK_EXCL);
+               if (error)
+diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
+index 020e0a412287a..8cd0c3df253f9 100644
+--- a/fs/xfs/xfs_file.c
++++ b/fs/xfs/xfs_file.c
+@@ -909,7 +909,6 @@ xfs_file_fallocate(
+       struct inode            *inode = file_inode(file);
+       struct xfs_inode        *ip = XFS_I(inode);
+       long                    error;
+-      enum xfs_prealloc_flags flags = 0;
+       uint                    iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
+       loff_t                  new_size = 0;
+       bool                    do_file_insert = false;
+@@ -1007,8 +1006,6 @@ xfs_file_fallocate(
+               }
+               do_file_insert = true;
+       } else {
+-              flags |= XFS_PREALLOC_SET;
+-
+               if (!(mode & FALLOC_FL_KEEP_SIZE) &&
+                   offset + len > i_size_read(inode)) {
+                       new_size = offset + len;
+@@ -1059,11 +1056,6 @@ xfs_file_fallocate(
+                       if (error)
+                               goto out_unlock;
+               }
+-
+-              error = xfs_update_prealloc_flags(ip, XFS_PREALLOC_SET);
+-              if (error)
+-                      goto out_unlock;
+-
+       }
+       /* Change file size if needed */
+-- 
+2.39.2
+
diff --git a/queue-5.15/xfs-use-setattr_copy-to-set-vfs-inode-attributes.patch b/queue-5.15/xfs-use-setattr_copy-to-set-vfs-inode-attributes.patch
new file mode 100644 (file)
index 0000000..0cc4016
--- /dev/null
@@ -0,0 +1,161 @@
+From 56b19146aae8a2c743cf53881605414b4c70c718 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Mar 2023 10:59:12 -0800
+Subject: xfs: use setattr_copy to set vfs inode attributes
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit e014f37db1a2d109afa750042ac4d69cf3e3d88e upsream.
+
+Filipe Manana pointed out that XFS' behavior w.r.t. setuid/setgid
+revocation isn't consistent with btrfs[1] or ext4.  Those two
+filesystems use the VFS function setattr_copy to convey certain
+attributes from struct iattr into the VFS inode structure.
+
+Andrey Zhadchenko reported[2] that XFS uses the wrong user namespace to
+decide if it should clear setgid and setuid on a file attribute update.
+This is a second symptom of the problem that Filipe noticed.
+
+XFS, on the other hand, open-codes setattr_copy in xfs_setattr_mode,
+xfs_setattr_nonsize, and xfs_setattr_time.  Regrettably, setattr_copy is
+/not/ a simple copy function; it contains additional logic to clear the
+setgid bit when setting the mode, and XFS' version no longer matches.
+
+The VFS implements its own setuid/setgid stripping logic, which
+establishes consistent behavior.  It's a tad unfortunate that it's
+scattered across notify_change, should_remove_suid, and setattr_copy but
+XFS should really follow the Linux VFS.  Adapt XFS to use the VFS
+functions and get rid of the old functions.
+
+[1] https://lore.kernel.org/fstests/CAL3q7H47iNQ=Wmk83WcGB-KBJVOEtR9+qGczzCeXJ9Y2KCV25Q@mail.gmail.com/
+[2] https://lore.kernel.org/linux-xfs/20220221182218.748084-1-andrey.zhadchenko@virtuozzo.com/
+
+Fixes: 7fa294c8991c ("userns: Allow chown and setgid preservation")
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/xfs_iops.c | 56 +++--------------------------------------------
+ fs/xfs/xfs_pnfs.c |  3 ++-
+ 2 files changed, 5 insertions(+), 54 deletions(-)
+
+diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
+index a607d6aca5c4d..1eb71275e5b09 100644
+--- a/fs/xfs/xfs_iops.c
++++ b/fs/xfs/xfs_iops.c
+@@ -634,37 +634,6 @@ xfs_vn_getattr(
+       return 0;
+ }
+-static void
+-xfs_setattr_mode(
+-      struct xfs_inode        *ip,
+-      struct iattr            *iattr)
+-{
+-      struct inode            *inode = VFS_I(ip);
+-      umode_t                 mode = iattr->ia_mode;
+-
+-      ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+-
+-      inode->i_mode &= S_IFMT;
+-      inode->i_mode |= mode & ~S_IFMT;
+-}
+-
+-void
+-xfs_setattr_time(
+-      struct xfs_inode        *ip,
+-      struct iattr            *iattr)
+-{
+-      struct inode            *inode = VFS_I(ip);
+-
+-      ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+-
+-      if (iattr->ia_valid & ATTR_ATIME)
+-              inode->i_atime = iattr->ia_atime;
+-      if (iattr->ia_valid & ATTR_CTIME)
+-              inode->i_ctime = iattr->ia_ctime;
+-      if (iattr->ia_valid & ATTR_MTIME)
+-              inode->i_mtime = iattr->ia_mtime;
+-}
+-
+ static int
+ xfs_vn_change_ok(
+       struct user_namespace   *mnt_userns,
+@@ -763,16 +732,6 @@ xfs_setattr_nonsize(
+               gid = (mask & ATTR_GID) ? iattr->ia_gid : igid;
+               uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid;
+-              /*
+-               * CAP_FSETID overrides the following restrictions:
+-               *
+-               * The set-user-ID and set-group-ID bits of a file will be
+-               * cleared upon successful return from chown()
+-               */
+-              if ((inode->i_mode & (S_ISUID|S_ISGID)) &&
+-                  !capable(CAP_FSETID))
+-                      inode->i_mode &= ~(S_ISUID|S_ISGID);
+-
+               /*
+                * Change the ownerships and register quota modifications
+                * in the transaction.
+@@ -784,7 +743,6 @@ xfs_setattr_nonsize(
+                               olddquot1 = xfs_qm_vop_chown(tp, ip,
+                                                       &ip->i_udquot, udqp);
+                       }
+-                      inode->i_uid = uid;
+               }
+               if (!gid_eq(igid, gid)) {
+                       if (XFS_IS_GQUOTA_ON(mp)) {
+@@ -795,15 +753,10 @@ xfs_setattr_nonsize(
+                               olddquot2 = xfs_qm_vop_chown(tp, ip,
+                                                       &ip->i_gdquot, gdqp);
+                       }
+-                      inode->i_gid = gid;
+               }
+       }
+-      if (mask & ATTR_MODE)
+-              xfs_setattr_mode(ip, iattr);
+-      if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
+-              xfs_setattr_time(ip, iattr);
+-
++      setattr_copy(mnt_userns, inode, iattr);
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+       XFS_STATS_INC(mp, xs_ig_attrchg);
+@@ -1028,11 +981,8 @@ xfs_setattr_size(
+               xfs_inode_clear_eofblocks_tag(ip);
+       }
+-      if (iattr->ia_valid & ATTR_MODE)
+-              xfs_setattr_mode(ip, iattr);
+-      if (iattr->ia_valid & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
+-              xfs_setattr_time(ip, iattr);
+-
++      ASSERT(!(iattr->ia_valid & (ATTR_UID | ATTR_GID)));
++      setattr_copy(mnt_userns, inode, iattr);
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+       XFS_STATS_INC(mp, xs_ig_attrchg);
+diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
+index 5e1d29d8b2e73..8865f7d4404ae 100644
+--- a/fs/xfs/xfs_pnfs.c
++++ b/fs/xfs/xfs_pnfs.c
+@@ -283,7 +283,8 @@ xfs_fs_commit_blocks(
+       xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+-      xfs_setattr_time(ip, iattr);
++      ASSERT(!(iattr->ia_valid & (ATTR_UID | ATTR_GID)));
++      setattr_copy(&init_user_ns, inode, iattr);
+       if (update_isize) {
+               i_size_write(inode, iattr->ia_size);
+               ip->i_disk_size = iattr->ia_size;
+-- 
+2.39.2
+