]>
Commit | Line | Data |
---|---|---|
ae271c1b MS |
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 */ |