+++ /dev/null
-From c7423dbdbc9ecef7fff5239d144cad4b9887f4de Mon Sep 17 00:00:00 2001
-From: GUO Zihua <guozihua@huawei.com>
-Date: Wed, 21 Sep 2022 20:58:04 +0800
-Subject: ima: Handle -ESTALE returned by ima_filter_rule_match()
-
-From: GUO Zihua <guozihua@huawei.com>
-
-commit c7423dbdbc9ecef7fff5239d144cad4b9887f4de upstream.
-
-IMA relies on the blocking LSM policy notifier callback to update the
-LSM based IMA policy rules.
-
-When SELinux update its policies, IMA would be notified and starts
-updating all its lsm rules one-by-one. During this time, -ESTALE would
-be returned by ima_filter_rule_match() if it is called with a LSM rule
-that has not yet been updated. In ima_match_rules(), -ESTALE is not
-handled, and the LSM rule is considered a match, causing extra files
-to be measured by IMA.
-
-Fix it by re-initializing a temporary rule if -ESTALE is returned by
-ima_filter_rule_match(). The origin rule in the rule list would be
-updated by the LSM policy notifier callback.
-
-Fixes: b16942455193 ("ima: use the lsm policy update notifier")
-Signed-off-by: GUO Zihua <guozihua@huawei.com>
-Reviewed-by: Roberto Sassu <roberto.sassu@huawei.com>
-Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
-Signed-off-by: GUO Zihua <guozihua@huawei.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- security/integrity/ima/ima_policy.c | 37 ++++++++++++++++++++++++++++--------
- 1 file changed, 29 insertions(+), 8 deletions(-)
-
---- a/security/integrity/ima/ima_policy.c
-+++ b/security/integrity/ima/ima_policy.c
-@@ -375,6 +375,9 @@ static bool ima_match_rules(struct ima_r
- enum ima_hooks func, int mask)
- {
- int i;
-+ bool result = false;
-+ struct ima_rule_entry *lsm_rule = rule;
-+ bool rule_reinitialized = false;
-
- if ((rule->flags & IMA_FUNC) &&
- (rule->func != func && func != POST_SETATTR))
-@@ -413,35 +416,53 @@ static bool ima_match_rules(struct ima_r
- int rc = 0;
- u32 osid;
-
-- if (!rule->lsm[i].rule)
-+ if (!lsm_rule->lsm[i].rule)
- continue;
-
-+retry:
- switch (i) {
- case LSM_OBJ_USER:
- case LSM_OBJ_ROLE:
- case LSM_OBJ_TYPE:
- security_inode_getsecid(inode, &osid);
- rc = security_filter_rule_match(osid,
-- rule->lsm[i].type,
-+ lsm_rule->lsm[i].type,
- Audit_equal,
-- rule->lsm[i].rule,
-+ lsm_rule->lsm[i].rule,
- NULL);
- break;
- case LSM_SUBJ_USER:
- case LSM_SUBJ_ROLE:
- case LSM_SUBJ_TYPE:
- rc = security_filter_rule_match(secid,
-- rule->lsm[i].type,
-+ lsm_rule->lsm[i].type,
- Audit_equal,
-- rule->lsm[i].rule,
-+ lsm_rule->lsm[i].rule,
- NULL);
- default:
- break;
- }
-- if (!rc)
-- return false;
-+
-+ if (rc == -ESTALE && !rule_reinitialized) {
-+ lsm_rule = ima_lsm_copy_rule(rule);
-+ if (lsm_rule) {
-+ rule_reinitialized = true;
-+ goto retry;
-+ }
-+ }
-+ if (!rc) {
-+ result = false;
-+ goto out;
-+ }
-+ }
-+ result = true;
-+
-+out:
-+ if (rule_reinitialized) {
-+ ima_lsm_free_rule(lsm_rule);
-+ kfree(lsm_rule);
- }
-- return true;
-+ return result;
- }
-
- /*
+++ /dev/null
-From b169424551930a9325f700f502802f4d515194e5 Mon Sep 17 00:00:00 2001
-From: Janne Karhunen <janne.karhunen@gmail.com>
-Date: Fri, 14 Jun 2019 15:20:15 +0300
-Subject: ima: use the lsm policy update notifier
-
-From: Janne Karhunen <janne.karhunen@gmail.com>
-
-commit b169424551930a9325f700f502802f4d515194e5 upstream.
-
-Don't do lazy policy updates while running the rule matching,
-run the updates as they happen.
-
-Depends on commit f242064c5df3 ("LSM: switch to blocking policy update notifiers")
-
-Signed-off-by: Janne Karhunen <janne.karhunen@gmail.com>
-Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
-Signed-off-by: GUO Zihua <guozihua@huawei.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- security/integrity/ima/ima.h | 2
- security/integrity/ima/ima_main.c | 8 ++
- security/integrity/ima/ima_policy.c | 118 ++++++++++++++++++++++++++++--------
- 3 files changed, 105 insertions(+), 23 deletions(-)
-
---- a/security/integrity/ima/ima.h
-+++ b/security/integrity/ima/ima.h
-@@ -154,6 +154,8 @@ int ima_measurements_show(struct seq_fil
- unsigned long ima_get_binary_runtime_size(void);
- int ima_init_template(void);
- void ima_init_template_list(void);
-+int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
-+ void *lsm_data);
-
- /*
- * used to protect h_table and sha_table
---- a/security/integrity/ima/ima_main.c
-+++ b/security/integrity/ima/ima_main.c
-@@ -41,6 +41,10 @@ int ima_appraise;
- int ima_hash_algo = HASH_ALGO_SHA1;
- static int hash_setup_done;
-
-+static struct notifier_block ima_lsm_policy_notifier = {
-+ .notifier_call = ima_lsm_policy_change,
-+};
-+
- static int __init hash_setup(char *str)
- {
- struct ima_template_desc *template_desc = ima_template_desc_current();
-@@ -553,6 +557,10 @@ static int __init init_ima(void)
- error = ima_init();
- }
-
-+ error = register_blocking_lsm_notifier(&ima_lsm_policy_notifier);
-+ if (error)
-+ pr_warn("Couldn't register LSM notifier, error %d\n", error);
-+
- if (!error)
- ima_update_policy_flag();
-
---- a/security/integrity/ima/ima_policy.c
-+++ b/security/integrity/ima/ima_policy.c
-@@ -241,46 +241,124 @@ static int __init default_appraise_polic
- }
- __setup("ima_appraise_tcb", default_appraise_policy_setup);
-
--static void ima_free_rule(struct ima_rule_entry *entry)
-+static void ima_lsm_free_rule(struct ima_rule_entry *entry)
- {
- int i;
-
-+ for (i = 0; i < MAX_LSM_RULES; i++) {
-+ security_filter_rule_free(entry->lsm[i].rule);
-+ kfree(entry->lsm[i].args_p);
-+ }
-+}
-+
-+static void ima_free_rule(struct ima_rule_entry *entry)
-+{
- if (!entry)
- return;
-
- kfree(entry->fsname);
-+ ima_lsm_free_rule(entry);
-+ kfree(entry);
-+}
-+
-+static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
-+{
-+ struct ima_rule_entry *nentry;
-+ int i, result;
-+
-+ nentry = kmalloc(sizeof(*nentry), GFP_KERNEL);
-+ if (!nentry)
-+ return NULL;
-+
-+ /*
-+ * Immutable elements are copied over as pointers and data; only
-+ * lsm rules can change
-+ */
-+ memcpy(nentry, entry, sizeof(*nentry));
-+ memset(nentry->lsm, 0, FIELD_SIZEOF(struct ima_rule_entry, lsm));
-+
- for (i = 0; i < MAX_LSM_RULES; i++) {
-- security_filter_rule_free(entry->lsm[i].rule);
-- kfree(entry->lsm[i].args_p);
-+ if (!entry->lsm[i].rule)
-+ continue;
-+
-+ nentry->lsm[i].type = entry->lsm[i].type;
-+ nentry->lsm[i].args_p = kstrdup(entry->lsm[i].args_p,
-+ GFP_KERNEL);
-+ if (!nentry->lsm[i].args_p)
-+ goto out_err;
-+
-+ result = security_filter_rule_init(nentry->lsm[i].type,
-+ Audit_equal,
-+ nentry->lsm[i].args_p,
-+ &nentry->lsm[i].rule);
-+ if (result == -EINVAL)
-+ pr_warn("ima: rule for LSM \'%d\' is undefined\n",
-+ entry->lsm[i].type);
- }
-+ return nentry;
-+
-+out_err:
-+ ima_lsm_free_rule(nentry);
-+ kfree(nentry);
-+ return NULL;
-+}
-+
-+static int ima_lsm_update_rule(struct ima_rule_entry *entry)
-+{
-+ struct ima_rule_entry *nentry;
-+
-+ nentry = ima_lsm_copy_rule(entry);
-+ if (!nentry)
-+ return -ENOMEM;
-+
-+ list_replace_rcu(&entry->list, &nentry->list);
-+ synchronize_rcu();
-+ ima_lsm_free_rule(entry);
- kfree(entry);
-+
-+ return 0;
- }
-
- /*
- * The LSM policy can be reloaded, leaving the IMA LSM based rules referring
- * to the old, stale LSM policy. Update the IMA LSM based rules to reflect
-- * the reloaded LSM policy. We assume the rules still exist; and BUG_ON() if
-- * they don't.
-+ * the reloaded LSM policy.
- */
- static void ima_lsm_update_rules(void)
- {
-- struct ima_rule_entry *entry;
-- int result;
-- int i;
-+ struct ima_rule_entry *entry, *e;
-+ int i, result, needs_update;
-
-- list_for_each_entry(entry, &ima_policy_rules, list) {
-+ list_for_each_entry_safe(entry, e, &ima_policy_rules, list) {
-+ needs_update = 0;
- for (i = 0; i < MAX_LSM_RULES; i++) {
-- if (!entry->lsm[i].rule)
-- continue;
-- result = security_filter_rule_init(entry->lsm[i].type,
-- Audit_equal,
-- entry->lsm[i].args_p,
-- &entry->lsm[i].rule);
-- BUG_ON(!entry->lsm[i].rule);
-+ if (entry->lsm[i].rule) {
-+ needs_update = 1;
-+ break;
-+ }
-+ }
-+ if (!needs_update)
-+ continue;
-+
-+ result = ima_lsm_update_rule(entry);
-+ if (result) {
-+ pr_err("ima: lsm rule update error %d\n",
-+ result);
-+ return;
- }
- }
- }
-
-+int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
-+ void *lsm_data)
-+{
-+ if (event != LSM_POLICY_CHANGE)
-+ return NOTIFY_DONE;
-+
-+ ima_lsm_update_rules();
-+ return NOTIFY_OK;
-+}
-+
- /**
- * ima_match_rules - determine whether an inode matches the measure rule.
- * @rule: a pointer to a rule
-@@ -334,11 +412,10 @@ static bool ima_match_rules(struct ima_r
- for (i = 0; i < MAX_LSM_RULES; i++) {
- int rc = 0;
- u32 osid;
-- int retried = 0;
-
- if (!rule->lsm[i].rule)
- continue;
--retry:
-+
- switch (i) {
- case LSM_OBJ_USER:
- case LSM_OBJ_ROLE:
-@@ -361,11 +438,6 @@ retry:
- default:
- break;
- }
-- if ((rc < 0) && (!retried)) {
-- retried = 1;
-- ima_lsm_update_rules();
-- goto retry;
-- }
- if (!rc)
- return false;
- }
+++ /dev/null
-From 42df744c4166af6959eda2df1ee5cde744d4a1c3 Mon Sep 17 00:00:00 2001
-From: Janne Karhunen <janne.karhunen@gmail.com>
-Date: Fri, 14 Jun 2019 15:20:14 +0300
-Subject: LSM: switch to blocking policy update notifiers
-
-From: Janne Karhunen <janne.karhunen@gmail.com>
-
-commit 42df744c4166af6959eda2df1ee5cde744d4a1c3 upstream.
-
-Atomic policy updaters are not very useful as they cannot
-usually perform the policy updates on their own. Since it
-seems that there is no strict need for the atomicity,
-switch to the blocking variant. While doing so, rename
-the functions accordingly.
-
-Signed-off-by: Janne Karhunen <janne.karhunen@gmail.com>
-Acked-by: Paul Moore <paul@paul-moore.com>
-Acked-by: James Morris <jamorris@linux.microsoft.com>
-Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
-Signed-off-by: GUO Zihua <guozihua@huawei.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/infiniband/core/device.c | 4 ++--
- include/linux/security.h | 12 ++++++------
- security/security.c | 23 +++++++++++++----------
- security/selinux/hooks.c | 2 +-
- security/selinux/selinuxfs.c | 2 +-
- 5 files changed, 23 insertions(+), 20 deletions(-)
-
---- a/drivers/infiniband/core/device.c
-+++ b/drivers/infiniband/core/device.c
-@@ -1207,7 +1207,7 @@ static int __init ib_core_init(void)
- goto err_mad;
- }
-
-- ret = register_lsm_notifier(&ibdev_lsm_nb);
-+ ret = register_blocking_lsm_notifier(&ibdev_lsm_nb);
- if (ret) {
- pr_warn("Couldn't register LSM notifier. ret %d\n", ret);
- goto err_sa;
-@@ -1243,7 +1243,7 @@ static void __exit ib_core_cleanup(void)
- roce_gid_mgmt_cleanup();
- nldev_exit();
- rdma_nl_unregister(RDMA_NL_LS);
-- unregister_lsm_notifier(&ibdev_lsm_nb);
-+ unregister_blocking_lsm_notifier(&ibdev_lsm_nb);
- ib_sa_cleanup();
- ib_mad_cleanup();
- addr_cleanup();
---- a/include/linux/security.h
-+++ b/include/linux/security.h
-@@ -191,9 +191,9 @@ struct security_mnt_opts {
- int num_mnt_opts;
- };
-
--int call_lsm_notifier(enum lsm_event event, void *data);
--int register_lsm_notifier(struct notifier_block *nb);
--int unregister_lsm_notifier(struct notifier_block *nb);
-+int call_blocking_lsm_notifier(enum lsm_event event, void *data);
-+int register_blocking_lsm_notifier(struct notifier_block *nb);
-+int unregister_blocking_lsm_notifier(struct notifier_block *nb);
-
- static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
- {
-@@ -409,17 +409,17 @@ int security_inode_getsecctx(struct inod
- struct security_mnt_opts {
- };
-
--static inline int call_lsm_notifier(enum lsm_event event, void *data)
-+static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
- {
- return 0;
- }
-
--static inline int register_lsm_notifier(struct notifier_block *nb)
-+static inline int register_blocking_lsm_notifier(struct notifier_block *nb)
- {
- return 0;
- }
-
--static inline int unregister_lsm_notifier(struct notifier_block *nb)
-+static inline int unregister_blocking_lsm_notifier(struct notifier_block *nb)
- {
- return 0;
- }
---- a/security/security.c
-+++ b/security/security.c
-@@ -38,7 +38,7 @@
- #define SECURITY_NAME_MAX 10
-
- struct security_hook_heads security_hook_heads __lsm_ro_after_init;
--static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
-+static BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain);
-
- char *lsm_names;
- /* Boot-time LSM user choice */
-@@ -180,23 +180,26 @@ void __init security_add_hooks(struct se
- panic("%s - Cannot get early memory.\n", __func__);
- }
-
--int call_lsm_notifier(enum lsm_event event, void *data)
-+int call_blocking_lsm_notifier(enum lsm_event event, void *data)
- {
-- return atomic_notifier_call_chain(&lsm_notifier_chain, event, data);
-+ return blocking_notifier_call_chain(&blocking_lsm_notifier_chain,
-+ event, data);
- }
--EXPORT_SYMBOL(call_lsm_notifier);
-+EXPORT_SYMBOL(call_blocking_lsm_notifier);
-
--int register_lsm_notifier(struct notifier_block *nb)
-+int register_blocking_lsm_notifier(struct notifier_block *nb)
- {
-- return atomic_notifier_chain_register(&lsm_notifier_chain, nb);
-+ return blocking_notifier_chain_register(&blocking_lsm_notifier_chain,
-+ nb);
- }
--EXPORT_SYMBOL(register_lsm_notifier);
-+EXPORT_SYMBOL(register_blocking_lsm_notifier);
-
--int unregister_lsm_notifier(struct notifier_block *nb)
-+int unregister_blocking_lsm_notifier(struct notifier_block *nb)
- {
-- return atomic_notifier_chain_unregister(&lsm_notifier_chain, nb);
-+ return blocking_notifier_chain_unregister(&blocking_lsm_notifier_chain,
-+ nb);
- }
--EXPORT_SYMBOL(unregister_lsm_notifier);
-+EXPORT_SYMBOL(unregister_blocking_lsm_notifier);
-
- /*
- * Hook list operation macros.
---- a/security/selinux/hooks.c
-+++ b/security/selinux/hooks.c
-@@ -199,7 +199,7 @@ static int selinux_lsm_notifier_avc_call
- {
- if (event == AVC_CALLBACK_RESET) {
- sel_ib_pkey_flush();
-- call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
-+ call_blocking_lsm_notifier(LSM_POLICY_CHANGE, NULL);
- }
-
- return 0;
---- a/security/selinux/selinuxfs.c
-+++ b/security/selinux/selinuxfs.c
-@@ -180,7 +180,7 @@ static ssize_t sel_write_enforce(struct
- selnl_notify_setenforce(new_value);
- selinux_status_update_setenforce(state, new_value);
- if (!new_value)
-- call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
-+ call_blocking_lsm_notifier(LSM_POLICY_CHANGE, NULL);
- }
- length = count;
- out:
x86-entry-64-add-instruction-suffix-to-sysret.patch
arm-dts-imx-fix-pca9547-i2c-mux-node-name.patch
dmaengine-imx-sdma-fix-a-possible-memory-leak-in-sdm.patch
-lsm-switch-to-blocking-policy-update-notifiers.patch
-ima-use-the-lsm-policy-update-notifier.patch
-ima-handle-estale-returned-by-ima_filter_rule_match.patch
sysctl-add-a-new-register_sysctl_init-interface.patch
panic-unset-panic_on_warn-inside-panic.patch
exit-add-and-use-make_task_dead.patch