@@ -669,6 +669,17 @@ fsverity_signature
fsverity_signature=(TRUE|FALSE)
+anonymous_memory
+~~~~~~~~~~~~~~~~
+
+ This property can be used to allow or deny operations triggered by
+ anonymous memory. It evaluates to TRUE when a memory region
+ in the evaluation context is not backed by a file. It is controlled by
+ the ``IPE_PROP_ANONYMOUS_MEMORY`` config option.
+ The format of this property is::
+
+ anonymous_memory=(TRUE|FALSE)
+
Policy Examples
---------------
@@ -385,15 +385,16 @@ Anonymous Memory
Anonymous memory isn't treated any differently from any other access in IPE.
When anonymous memory is mapped with ``+X``, it still comes into the ``file_mmap``
or ``file_mprotect`` hook, but with a ``NULL`` file object. This is submitted to
-the evaluation, like any other file. However, all current trust properties will
-evaluate to false, as they are all file-based and the operation is not
-associated with a file.
+the evaluation, like any other file. However, except the ``anonymous_memory`` property,
+all current trust properties will evaluate to false, as they are all file-based and
+the operation is not associated with a file.
.. WARNING::
This also occurs with the ``kernel_load_data`` hook, when the kernel is
loading data from a userspace buffer that is not backed by a file. In this
- scenario all current trust properties will also evaluate to false.
+ scenario, all current trust properties except ``anonymous_memory`` will also evaluate
+ to false.
Securityfs Interface
~~~~~~~~~~~~~~~~~~~~
@@ -94,6 +94,16 @@ config IPE_PROP_FS_VERITY_BUILTIN_SIG
if unsure, answer Y.
+config IPE_PROP_ANONYMOUS_MEMORY
+ bool "Enable support for anonymous memory"
+ default y
+ help
+ This option enables the 'anonymous_memory' property within IPE
+ policies. The property evaluates to TRUE when a memory region
+ in the evaluation context is not backed by a file (i.e., it is
+ anonymous memory).
+
+ if unsure, answer Y.
endmenu
config SECURITY_IPE_KUNIT_TEST
@@ -59,6 +59,8 @@ static const char *const audit_prop_names[__IPE_PROP_MAX] = {
"fsverity_digest=",
"fsverity_signature=FALSE",
"fsverity_signature=TRUE",
+ "anonymous_memory=FALSE",
+ "anonymous_memory=TRUE",
};
/**
@@ -265,6 +265,28 @@ static bool evaluate_fsv_sig_true(const struct ipe_eval_ctx *const ctx)
}
#endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
+#ifdef CONFIG_IPE_PROP_ANONYMOUS_MEMORY
+static bool evaluate_anonymous_memory_false(const struct ipe_eval_ctx *const ctx)
+{
+ return !ctx->file;
+}
+
+static bool evaluate_anonymous_memory_true(const struct ipe_eval_ctx *const ctx)
+{
+ return !evaluate_anonymous_memory_false(ctx);
+}
+#else
+static bool evaluate_anonymous_memory_false(const struct ipe_eval_ctx *const ctx)
+{
+ return false;
+}
+
+static bool evaluate_anonymous_memory_true(const struct ipe_eval_ctx *const ctx)
+{
+ return false;
+}
+#endif /* CONFIG_IPE_PROP_ANONYMOUS_MEMORY */
+
/**
* evaluate_property() - Analyze @ctx against a rule property.
* @ctx: Supplies a pointer to the context to be evaluated.
@@ -297,6 +319,10 @@ static bool evaluate_property(const struct ipe_eval_ctx *const ctx,
return evaluate_fsv_sig_false(ctx);
case IPE_PROP_FSV_SIG_TRUE:
return evaluate_fsv_sig_true(ctx);
+ case IPE_PROP_ANON_MEM_FALSE:
+ return evaluate_anonymous_memory_false(ctx);
+ case IPE_PROP_ANON_MEM_TRUE:
+ return evaluate_anonymous_memory_true(ctx);
default:
return false;
}
@@ -39,6 +39,8 @@ enum ipe_prop_type {
IPE_PROP_FSV_DIGEST,
IPE_PROP_FSV_SIG_FALSE,
IPE_PROP_FSV_SIG_TRUE,
+ IPE_PROP_ANON_MEM_FALSE,
+ IPE_PROP_ANON_MEM_TRUE,
__IPE_PROP_MAX
};
@@ -281,6 +281,8 @@ static const match_table_t property_tokens = {
{IPE_PROP_FSV_DIGEST, "fsverity_digest=%s"},
{IPE_PROP_FSV_SIG_FALSE, "fsverity_signature=FALSE"},
{IPE_PROP_FSV_SIG_TRUE, "fsverity_signature=TRUE"},
+ {IPE_PROP_ANON_MEM_FALSE, "anonymous_memory=FALSE"},
+ {IPE_PROP_ANON_MEM_TRUE, "anonymous_memory=TRUE"},
{IPE_PROP_INVALID, NULL}
};
@@ -331,6 +333,8 @@ static int parse_property(char *t, struct ipe_rule *r)
case IPE_PROP_DMV_SIG_TRUE:
case IPE_PROP_FSV_SIG_FALSE:
case IPE_PROP_FSV_SIG_TRUE:
+ case IPE_PROP_ANON_MEM_FALSE:
+ case IPE_PROP_ANON_MEM_TRUE:
p->type = token;
break;
default:
Currently, all existing IPE properties evaluate to FALSE for operations triggered by anonymous memory regions. As a result, IPE falls back to the policy's default action for such operations. In policies where the default action is DENY, this behavior blocks all anonymous memory operations, rendering binaries that rely on anonymous memory unusable. This commit introduces a new IPE property, 'anonymous_memory', which evaluates to TRUE when an operation is triggered by an anonymous memory region. This allows administrators to explicitly allow or deny operations involving anonymous memory. Signed-off-by: Fan Wu <wufan@linux.microsoft.com> --- Documentation/admin-guide/LSM/ipe.rst | 11 +++++++++++ Documentation/security/ipe.rst | 9 +++++---- security/ipe/Kconfig | 10 ++++++++++ security/ipe/audit.c | 2 ++ security/ipe/eval.c | 26 ++++++++++++++++++++++++++ security/ipe/policy.h | 2 ++ security/ipe/policy_parser.c | 4 ++++ 7 files changed, 60 insertions(+), 4 deletions(-)