xref: /openbmc/linux/security/landlock/ruleset.h (revision fbb6b31a)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Landlock LSM - Ruleset management
4  *
5  * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net>
6  * Copyright © 2018-2020 ANSSI
7  */
8 
9 #ifndef _SECURITY_LANDLOCK_RULESET_H
10 #define _SECURITY_LANDLOCK_RULESET_H
11 
12 #include <linux/mutex.h>
13 #include <linux/rbtree.h>
14 #include <linux/refcount.h>
15 #include <linux/workqueue.h>
16 
17 #include "object.h"
18 
19 /**
20  * struct landlock_layer - Access rights for a given layer
21  */
22 struct landlock_layer {
23 	/**
24 	 * @level: Position of this layer in the layer stack.
25 	 */
26 	u16 level;
27 	/**
28 	 * @access: Bitfield of allowed actions on the kernel object.  They are
29 	 * relative to the object type (e.g. %LANDLOCK_ACTION_FS_READ).
30 	 */
31 	u16 access;
32 };
33 
34 /**
35  * struct landlock_rule - Access rights tied to an object
36  */
37 struct landlock_rule {
38 	/**
39 	 * @node: Node in the ruleset's red-black tree.
40 	 */
41 	struct rb_node node;
42 	/**
43 	 * @object: Pointer to identify a kernel object (e.g. an inode).  This
44 	 * is used as a key for this ruleset element.  This pointer is set once
45 	 * and never modified.  It always points to an allocated object because
46 	 * each rule increments the refcount of its object.
47 	 */
48 	struct landlock_object *object;
49 	/**
50 	 * @num_layers: Number of entries in @layers.
51 	 */
52 	u32 num_layers;
53 	/**
54 	 * @layers: Stack of layers, from the latest to the newest, implemented
55 	 * as a flexible array member (FAM).
56 	 */
57 	struct landlock_layer layers[];
58 };
59 
60 /**
61  * struct landlock_hierarchy - Node in a ruleset hierarchy
62  */
63 struct landlock_hierarchy {
64 	/**
65 	 * @parent: Pointer to the parent node, or NULL if it is a root
66 	 * Landlock domain.
67 	 */
68 	struct landlock_hierarchy *parent;
69 	/**
70 	 * @usage: Number of potential children domains plus their parent
71 	 * domain.
72 	 */
73 	refcount_t usage;
74 };
75 
76 /**
77  * struct landlock_ruleset - Landlock ruleset
78  *
79  * This data structure must contain unique entries, be updatable, and quick to
80  * match an object.
81  */
82 struct landlock_ruleset {
83 	/**
84 	 * @root: Root of a red-black tree containing &struct landlock_rule
85 	 * nodes.  Once a ruleset is tied to a process (i.e. as a domain), this
86 	 * tree is immutable until @usage reaches zero.
87 	 */
88 	struct rb_root root;
89 	/**
90 	 * @hierarchy: Enables hierarchy identification even when a parent
91 	 * domain vanishes.  This is needed for the ptrace protection.
92 	 */
93 	struct landlock_hierarchy *hierarchy;
94 	union {
95 		/**
96 		 * @work_free: Enables to free a ruleset within a lockless
97 		 * section.  This is only used by
98 		 * landlock_put_ruleset_deferred() when @usage reaches zero.
99 		 * The fields @lock, @usage, @num_rules, @num_layers and
100 		 * @fs_access_masks are then unused.
101 		 */
102 		struct work_struct work_free;
103 		struct {
104 			/**
105 			 * @lock: Protects against concurrent modifications of
106 			 * @root, if @usage is greater than zero.
107 			 */
108 			struct mutex lock;
109 			/**
110 			 * @usage: Number of processes (i.e. domains) or file
111 			 * descriptors referencing this ruleset.
112 			 */
113 			refcount_t usage;
114 			/**
115 			 * @num_rules: Number of non-overlapping (i.e. not for
116 			 * the same object) rules in this ruleset.
117 			 */
118 			u32 num_rules;
119 			/**
120 			 * @num_layers: Number of layers that are used in this
121 			 * ruleset.  This enables to check that all the layers
122 			 * allow an access request.  A value of 0 identifies a
123 			 * non-merged ruleset (i.e. not a domain).
124 			 */
125 			u32 num_layers;
126 			/**
127 			 * @fs_access_masks: Contains the subset of filesystem
128 			 * actions that are restricted by a ruleset.  A domain
129 			 * saves all layers of merged rulesets in a stack
130 			 * (FAM), starting from the first layer to the last
131 			 * one.  These layers are used when merging rulesets,
132 			 * for user space backward compatibility (i.e.
133 			 * future-proof), and to properly handle merged
134 			 * rulesets without overlapping access rights.  These
135 			 * layers are set once and never changed for the
136 			 * lifetime of the ruleset.
137 			 */
138 			u16 fs_access_masks[];
139 		};
140 	};
141 };
142 
143 struct landlock_ruleset *landlock_create_ruleset(const u32 fs_access_mask);
144 
145 void landlock_put_ruleset(struct landlock_ruleset *const ruleset);
146 void landlock_put_ruleset_deferred(struct landlock_ruleset *const ruleset);
147 
148 int landlock_insert_rule(struct landlock_ruleset *const ruleset,
149 		struct landlock_object *const object, const u32 access);
150 
151 struct landlock_ruleset *landlock_merge_ruleset(
152 		struct landlock_ruleset *const parent,
153 		struct landlock_ruleset *const ruleset);
154 
155 const struct landlock_rule *landlock_find_rule(
156 		const struct landlock_ruleset *const ruleset,
157 		const struct landlock_object *const object);
158 
159 static inline void landlock_get_ruleset(struct landlock_ruleset *const ruleset)
160 {
161 	if (ruleset)
162 		refcount_inc(&ruleset->usage);
163 }
164 
165 #endif /* _SECURITY_LANDLOCK_RULESET_H */
166