From 768b5503839b8f1445d95813e18be333ad5efc68 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 13 Mar 2023 22:17:12 -0400 Subject: [PATCH] Fixes for 5.15 Signed-off-by: Sasha Levin --- queue-5.15/attr-add-in_group_or_capable.patch | 125 ++ .../attr-add-setattr_should_drop_sgid.patch | 89 ++ ...use-consistent-sgid-stripping-checks.patch | 350 ++++++ .../fs-add-mode_strip_sgid-helper.patch | 104 ++ ...sgid-stripping-into-the-vfs_-helpers.patch | 354 ++++++ queue-5.15/fs-move-should_remove_suid.patch | 108 ++ ...-consistent-setgid-checks-in-is_sxid.patch | 46 + ...length-limitation-for-the-ivrs_acpih.patch | 73 ++ ...i-segment-support-for-ivrs_-ioapic-h.patch | 193 +++ ...l-formed-ivrs_ioapic-ivrs_hpet-and-i.patch | 217 ++++ .../irqdomain-fix-mapping-creation-race.patch | 184 +++ ...rrect-block_device-in-nbd_bdev_reset.patch | 82 ++ queue-5.15/series | 22 + ...l8723bs-clean-up-comparsions-to-null.patch | 1053 +++++++++++++++++ ...l8723bs-fix-key-store-index-handling.patch | 183 +++ ...ng-rtl8723bs-fix-placement-of-braces.patch | 602 ++++++++++ ...s-placing-opening-braces-in-previous.patch | 261 ++++ ...-t-abort-tpm_read_log-on-faulty-acpi.patch | 73 ++ ...ioc_watch_queue_set_size-alloc-error.patch | 39 + ...-fallocate-should-call-file_modified.patch | 71 ++ queue-5.15/xfs-remove-xfs_prealloc_sync.patch | 89 ++ ...realloc-flag-in-xfs_alloc_file_space.patch | 95 ++ ...ttr_copy-to-set-vfs-inode-attributes.patch | 161 +++ 23 files changed, 4574 insertions(+) create mode 100644 queue-5.15/attr-add-in_group_or_capable.patch create mode 100644 queue-5.15/attr-add-setattr_should_drop_sgid.patch create mode 100644 queue-5.15/attr-use-consistent-sgid-stripping-checks.patch create mode 100644 queue-5.15/fs-add-mode_strip_sgid-helper.patch create mode 100644 queue-5.15/fs-move-s_isgid-stripping-into-the-vfs_-helpers.patch create mode 100644 queue-5.15/fs-move-should_remove_suid.patch create mode 100644 queue-5.15/fs-use-consistent-setgid-checks-in-is_sxid.patch create mode 100644 queue-5.15/iommu-amd-add-a-length-limitation-for-the-ivrs_acpih.patch create mode 100644 queue-5.15/iommu-amd-add-pci-segment-support-for-ivrs_-ioapic-h.patch create mode 100644 queue-5.15/iommu-amd-fix-ill-formed-ivrs_ioapic-ivrs_hpet-and-i.patch create mode 100644 queue-5.15/irqdomain-fix-mapping-creation-race.patch create mode 100644 queue-5.15/nbd-use-the-correct-block_device-in-nbd_bdev_reset.patch create mode 100644 queue-5.15/staging-rtl8723bs-clean-up-comparsions-to-null.patch create mode 100644 queue-5.15/staging-rtl8723bs-fix-key-store-index-handling.patch create mode 100644 queue-5.15/staging-rtl8723bs-fix-placement-of-braces.patch create mode 100644 queue-5.15/staging-rtl8723bs-placing-opening-braces-in-previous.patch create mode 100644 queue-5.15/tpm-eventlog-don-t-abort-tpm_read_log-on-faulty-acpi.patch create mode 100644 queue-5.15/watch_queue-fix-ioc_watch_queue_set_size-alloc-error.patch create mode 100644 queue-5.15/xfs-fallocate-should-call-file_modified.patch create mode 100644 queue-5.15/xfs-remove-xfs_prealloc_sync.patch create mode 100644 queue-5.15/xfs-set-prealloc-flag-in-xfs_alloc_file_space.patch create mode 100644 queue-5.15/xfs-use-setattr_copy-to-set-vfs-inode-attributes.patch 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 index 00000000000..2ceb29f413c --- /dev/null +++ b/queue-5.15/attr-add-in_group_or_capable.patch @@ -0,0 +1,125 @@ +From 8b129e70cf645e8e7f1a6a14e97db0068c8e6276 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:18 -0800 +Subject: attr: add in_group_or_capable() + +From: Christian Brauner + +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 +Signed-off-by: Christian Brauner (Microsoft) +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 + #include + ++#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 index 00000000000..aa118a86c9c --- /dev/null +++ b/queue-5.15/attr-add-setattr_should_drop_sgid.patch @@ -0,0 +1,89 @@ +From fdba6071d3b7bd547ea334d8b9a69ccf07bfbfcd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:20 -0800 +Subject: attr: add setattr_should_drop_sgid() + +From: Christian Brauner + +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 +Signed-off-by: Christian Brauner (Microsoft) +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..4a0f0b18f92 --- /dev/null +++ b/queue-5.15/attr-use-consistent-sgid-stripping-checks.patch @@ -0,0 +1,350 @@ +From fb111ba84f9782fa9d00fe857c578321fdf60658 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:21 -0800 +Subject: attr: use consistent sgid stripping checks + +From: Christian Brauner + +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 +Signed-off-by: Christian Brauner (Microsoft) +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..1a5fca88fd3 --- /dev/null +++ b/queue-5.15/fs-add-mode_strip_sgid-helper.patch @@ -0,0 +1,104 @@ +From 80a4bd6121353782815eb919865483ed4a7a414f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:16 -0800 +Subject: fs: add mode_strip_sgid() helper + +From: Yang Xu + +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 +Reviewed-by: Christian Brauner (Microsoft) +Reviewed-and-Tested-by: Jeff Layton +Signed-off-by: Yang Xu +Signed-off-by: Christian Brauner (Microsoft) +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..88631e31e15 --- /dev/null +++ b/queue-5.15/fs-move-s_isgid-stripping-into-the-vfs_-helpers.patch @@ -0,0 +1,354 @@ +From 1f0af87a30c99969ad586ca55ba5c4c2b00f0dfb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:17 -0800 +Subject: fs: move S_ISGID stripping into the vfs_*() helpers + +From: Yang Xu + +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 +Suggested-by: Christian Brauner (Microsoft) +Reviewed-by: Darrick J. Wong +Reviewed-and-Tested-by: Jeff Layton +Signed-off-by: Yang Xu +[: rewrote commit message] +Signed-off-by: Christian Brauner (Microsoft) +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a44c00f7f0e --- /dev/null +++ b/queue-5.15/fs-move-should_remove_suid.patch @@ -0,0 +1,108 @@ +From 848d854458122c791de5912b9de0f621badb04bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:19 -0800 +Subject: fs: move should_remove_suid() + +From: Christian Brauner + +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 +Signed-off-by: Christian Brauner (Microsoft) +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..cfc187e748e --- /dev/null +++ b/queue-5.15/fs-use-consistent-setgid-checks-in-is_sxid.patch @@ -0,0 +1,46 @@ +From 3a27dd1a0eb7c05d001d126d952f5075d5cb3cfc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:22 -0800 +Subject: fs: use consistent setgid checks in is_sxid() + +From: Christian Brauner + +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 +Signed-off-by: Christian Brauner (Microsoft) +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..5d451caa128 --- /dev/null +++ b/queue-5.15/iommu-amd-add-a-length-limitation-for-the-ivrs_acpih.patch @@ -0,0 +1,73 @@ +From f95bbac94d96e3d7999c616778397948e788d500 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Kim Phillips +Link: https://lore.kernel.org/r/20230202082719.1513849-1-Ilia.Gavrilov@infotecs.ru +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ddf85b83dea --- /dev/null +++ b/queue-5.15/iommu-amd-add-pci-segment-support-for-ivrs_-ioapic-h.patch @@ -0,0 +1,193 @@ +From 3c18ee515ee86665867f0292e4e06c1541c257cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Vasant Hegde +Signed-off-by: Suravee Suthikulpanit +Link: https://lore.kernel.org/r/20220706113825.25582-33-vasant.hegde@amd.com +Signed-off-by: Joerg Roedel +Stable-dep-of: b6b26d86c61c ("iommu/amd: Add a length limitation for the ivrs_acpihid command-line parameter") +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..e8ce90a3837 --- /dev/null +++ b/queue-5.15/iommu-amd-fix-ill-formed-ivrs_ioapic-ivrs_hpet-and-i.patch @@ -0,0 +1,217 @@ +From dc5e3d9d7c18b7f9dcb8bf4c1cf02cfefad299ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Co-developed-by: Suravee Suthikulpanit +Signed-off-by: Suravee Suthikulpanit +Signed-off-by: Kim Phillips +Link: https://lore.kernel.org/r/20220919155638.391481-2-kim.phillips@amd.com +Signed-off-by: Joerg Roedel +Stable-dep-of: b6b26d86c61c ("iommu/amd: Add a length limitation for the ivrs_acpihid command-line parameter") +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..346d91cbd1d --- /dev/null +++ b/queue-5.15/irqdomain-fix-mapping-creation-race.patch @@ -0,0 +1,184 @@ +From 2c4dbc49aca94706c550e5bea18e1647dc03a001 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Feb 2023 11:42:48 +0100 +Subject: irqdomain: Fix mapping-creation race + +From: Johan Hovold + +[ 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 +Cc: Jon Hunter +Tested-by: Hsin-Yi Wang +Tested-by: Mark-PK Tsai +Signed-off-by: Johan Hovold +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20230213104302.17307-7-johan+linaro@kernel.org +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ceb7f1a694e --- /dev/null +++ b/queue-5.15/nbd-use-the-correct-block_device-in-nbd_bdev_reset.patch @@ -0,0 +1,82 @@ +From f022ff9b48467b05cf4b294a6bd75d036ae13486 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Mar 2022 07:29:03 +0200 +Subject: nbd: use the correct block_device in nbd_bdev_reset + +From: Christoph Hellwig + +[ 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 +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20220330052917.2566582-2-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: e5cfefa97bcc ("block: fix scan partition for exclusively open device again") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/series b/queue-5.15/series index ca89a84a260..1b45d68c1aa 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -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 index 00000000000..8c49025cbbf --- /dev/null +++ b/queue-5.15/staging-rtl8723bs-clean-up-comparsions-to-null.patch @@ -0,0 +1,1053 @@ +From 8c5a283820d4ad87f765f895fe00bea5497b10cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 29 Aug 2021 17:45:33 +0200 +Subject: staging: rtl8723bs: clean up comparsions to NULL + +From: Michael Straube + +[ Upstream commit cd1f1450092216b3e39516f8db58869b6fc20575 ] + +Clean up comparsions to NULL reported by checkpatch. + +x == NULL -> !x +x != NULL -> x + +Signed-off-by: Michael Straube +Link: https://lore.kernel.org/r/20210829154533.11054-1-straube.linux@gmail.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 05cbcc415c9b ("staging: rtl8723bs: Fix key-store index handling") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..6c338ff02ac --- /dev/null +++ b/queue-5.15/staging-rtl8723bs-fix-key-store-index-handling.patch @@ -0,0 +1,183 @@ +From d3b57f3361d05a5b0b03b863fd47307f0cec6ee7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Mar 2023 16:35:11 +0100 +Subject: staging: rtl8723bs: Fix key-store index handling + +From: Hans de Goede + +[ 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 +Link: https://lore.kernel.org/r/20230306153512.162104-1-hdegoede@redhat.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..706e68b2940 --- /dev/null +++ b/queue-5.15/staging-rtl8723bs-fix-placement-of-braces.patch @@ -0,0 +1,602 @@ +From d463310beae64ddc2445b2e280131864634e6c21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 28 May 2022 14:31:15 +0200 +Subject: staging: rtl8723bs: fix placement of braces + +From: Hannes Braun + +[ 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 +Link: https://lore.kernel.org/r/20220528123115.13024-1-hannesbraun@mail.de +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 05cbcc415c9b ("staging: rtl8723bs: Fix key-store index handling") +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..17256011ebf --- /dev/null +++ b/queue-5.15/staging-rtl8723bs-placing-opening-braces-in-previous.patch @@ -0,0 +1,261 @@ +From ae2b09751e9377de8a482d56e363f92cccb01d96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Jan 2022 09:14:54 +0530 +Subject: Staging: rtl8723bs: Placing opening { braces in previous line + +From: Jagath Jog J + +[ 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 +Signed-off-by: Jagath Jog J +Link: https://lore.kernel.org/r/20220124034456.8665-2-jagathjog1996@gmail.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 05cbcc415c9b ("staging: rtl8723bs: Fix key-store index handling") +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..ae7067800c8 --- /dev/null +++ b/queue-5.15/tpm-eventlog-don-t-abort-tpm_read_log-on-faulty-acpi.patch @@ -0,0 +1,73 @@ +From b8e38b713d9cf62b761c2af3dcef58380152214c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Morten Linderud +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e02cc057474 --- /dev/null +++ b/queue-5.15/watch_queue-fix-ioc_watch_queue_set_size-alloc-error.patch @@ -0,0 +1,39 @@ +From f64f2da35cfb3521462ecec2efd2c67ad4b09381 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 16:21:06 +0100 +Subject: watch_queue: fix IOC_WATCH_QUEUE_SET_SIZE alloc error paths + +From: David Disseldorp + +[ 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 +Signed-off-by: Christian Brauner (Microsoft) +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..b664793921a --- /dev/null +++ b/queue-5.15/xfs-fallocate-should-call-file_modified.patch @@ -0,0 +1,71 @@ +From e5772e2e8f1bfd5feeb4caa9e37d2a6600aa82de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:14 -0800 +Subject: xfs: fallocate() should call file_modified() + +From: Dave Chinner + +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 +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..4e06c07a8ab --- /dev/null +++ b/queue-5.15/xfs-remove-xfs_prealloc_sync.patch @@ -0,0 +1,89 @@ +From 562ab7efef31bd4458c90e038a0d630232e89b16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:13 -0800 +Subject: xfs: remove XFS_PREALLOC_SYNC + +From: Dave Chinner + +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 +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ca71a081e8a --- /dev/null +++ b/queue-5.15/xfs-set-prealloc-flag-in-xfs_alloc_file_space.patch @@ -0,0 +1,95 @@ +From 4eafcd9d73d2055b99e9547db132f08df7458c9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:15 -0800 +Subject: xfs: set prealloc flag in xfs_alloc_file_space() + +From: Dave Chinner + +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 +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0cc40167a62 --- /dev/null +++ b/queue-5.15/xfs-use-setattr_copy-to-set-vfs-inode-attributes.patch @@ -0,0 +1,161 @@ +From 56b19146aae8a2c743cf53881605414b4c70c718 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Mar 2023 10:59:12 -0800 +Subject: xfs: use setattr_copy to set vfs inode attributes + +From: Darrick J. Wong + +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 +Reviewed-by: Dave Chinner +Reviewed-by: Christoph Hellwig +Reviewed-by: Christian Brauner +Signed-off-by: Amir Goldstein +Tested-by: Leah Rumancik +Acked-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 + -- 2.47.3