[RFC PATCH v2 04/12] landlock/domain: Implement finding rules
Tingmao Wang
m at maowtm.org
Sun Jul 6 15:16:45 UTC 2025
This implements a function to search for matching rules using the newly
defined coalesced hashtable, and define convinience macros for fs and net
respectively, as well as a macro to iterate over the layers of the rule.
Signed-off-by: Tingmao Wang <m at maowtm.org>
---
security/landlock/domain.h | 67 ++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/security/landlock/domain.h b/security/landlock/domain.h
index b0f5ba59ff4c..8acd88a1d77a 100644
--- a/security/landlock/domain.h
+++ b/security/landlock/domain.h
@@ -22,6 +22,7 @@
#include "access.h"
#include "audit.h"
#include "ruleset.h"
+#include "coalesced_hash.h"
struct landlock_domain_index {
/**
@@ -146,6 +147,72 @@ struct landlock_domain {
sizeof(uintptr_t)) / \
sizeof(uintptr_t))
+/*
+ * We have to use an invalid layer_index to signal empty value as the key
+ * can be 0 for net rules.
+ */
+#define dom_index_is_empty(elem) ((elem)->layer_index == U32_MAX)
+
+DEFINE_COALESCED_HASH_TABLE(struct landlock_domain_index, dom_hash, key,
+ next_collision,
+ hash_long(elem->key.data, 32) % table_size,
+ dom_index_is_empty(elem))
+
+struct landlock_found_rule {
+ const struct landlock_layer *layers_start;
+ const struct landlock_layer *layers_end;
+};
+
+/**
+ * landlock_domain_find - search for a key in a domain. Don't use this
+ * function directly, but use one of the dom_find_index_*() macros
+ * instead.
+ *
+ * @indices_arr: The indices array to search in.
+ * @num_indices: The number of elements in @indices_arr.
+ * @layers_arr: The layers array.
+ * @num_layers: The number of elements in @layers_arr.
+ * @key: The key to search for.
+ */
+static inline struct landlock_found_rule
+landlock_domain_find(const struct landlock_domain_index *const indices_arr,
+ const u32 num_indices,
+ const struct landlock_layer *const layers_arr,
+ const u32 num_layers, const union landlock_key key)
+{
+ struct landlock_domain_index key_elem = {
+ .key = key,
+ };
+ struct landlock_found_rule out_found_rule = {};
+ const struct landlock_domain_index *found;
+
+ found = dom_hash_find(indices_arr, num_indices, &key_elem);
+
+ if (found) {
+ if (WARN_ON_ONCE(found->layer_index >= num_layers))
+ return out_found_rule;
+ out_found_rule.layers_start = &layers_arr[found->layer_index];
+ out_found_rule.layers_end =
+ &layers_arr[(found + 1)->layer_index];
+ }
+
+ return out_found_rule;
+}
+
+#define dom_find_index_fs(dom, key) \
+ landlock_domain_find(dom_fs_indices(dom), (dom)->num_fs_indices, \
+ dom_fs_layers(dom), (dom)->num_fs_layers, key)
+
+#define dom_find_index_net(dom, key) \
+ landlock_domain_find(dom_net_indices(dom), (dom)->num_net_indices, \
+ dom_net_layers(dom), (dom)->num_net_layers, key)
+
+#define dom_find_success(found_rule) ((found_rule).layers_start != NULL)
+
+#define dom_rule_for_each_layer(found_rule, layer) \
+ for (layer = (found_rule).layers_start; \
+ layer < (found_rule).layers_end; layer++)
+
enum landlock_log_status {
LANDLOCK_LOG_PENDING = 0,
LANDLOCK_LOG_RECORDED,
--
2.49.0
More information about the Linux-security-module-archive
mailing list