|
11 | 11 |
|
12 | 12 | #include <linux/bitops.h>
|
13 | 13 | #include <linux/build_bug.h>
|
| 14 | +#include <linux/kernel.h> |
14 | 15 | #include <linux/mutex.h>
|
15 | 16 | #include <linux/rbtree.h>
|
16 | 17 | #include <linux/refcount.h>
|
@@ -47,6 +48,15 @@ struct access_masks {
|
47 | 48 | access_mask_t scope : LANDLOCK_NUM_SCOPE;
|
48 | 49 | };
|
49 | 50 |
|
| 51 | +union access_masks_all { |
| 52 | + struct access_masks masks; |
| 53 | + u32 all; |
| 54 | +}; |
| 55 | + |
| 56 | +/* Makes sure all fields are covered. */ |
| 57 | +static_assert(sizeof(typeof_member(union access_masks_all, masks)) == |
| 58 | + sizeof(typeof_member(union access_masks_all, all))); |
| 59 | + |
50 | 60 | typedef u16 layer_mask_t;
|
51 | 61 | /* Makes sure all layers can be checked. */
|
52 | 62 | static_assert(BITS_PER_TYPE(layer_mask_t) >= LANDLOCK_MAX_NUM_LAYERS);
|
@@ -260,6 +270,61 @@ static inline void landlock_get_ruleset(struct landlock_ruleset *const ruleset)
|
260 | 270 | refcount_inc(&ruleset->usage);
|
261 | 271 | }
|
262 | 272 |
|
| 273 | +/** |
| 274 | + * landlock_union_access_masks - Return all access rights handled in the |
| 275 | + * domain |
| 276 | + * |
| 277 | + * @domain: Landlock ruleset (used as a domain) |
| 278 | + * |
| 279 | + * Returns: an access_masks result of the OR of all the domain's access masks. |
| 280 | + */ |
| 281 | +static inline struct access_masks |
| 282 | +landlock_union_access_masks(const struct landlock_ruleset *const domain) |
| 283 | +{ |
| 284 | + union access_masks_all matches = {}; |
| 285 | + size_t layer_level; |
| 286 | + |
| 287 | + for (layer_level = 0; layer_level < domain->num_layers; layer_level++) { |
| 288 | + union access_masks_all layer = { |
| 289 | + .masks = domain->access_masks[layer_level], |
| 290 | + }; |
| 291 | + |
| 292 | + matches.all |= layer.all; |
| 293 | + } |
| 294 | + |
| 295 | + return matches.masks; |
| 296 | +} |
| 297 | + |
| 298 | +/** |
| 299 | + * landlock_get_applicable_domain - Return @domain if it applies to (handles) |
| 300 | + * at least one of the access rights specified |
| 301 | + * in @masks |
| 302 | + * |
| 303 | + * @domain: Landlock ruleset (used as a domain) |
| 304 | + * @masks: access masks |
| 305 | + * |
| 306 | + * Returns: @domain if any access rights specified in @masks is handled, or |
| 307 | + * NULL otherwise. |
| 308 | + */ |
| 309 | +static inline const struct landlock_ruleset * |
| 310 | +landlock_get_applicable_domain(const struct landlock_ruleset *const domain, |
| 311 | + const struct access_masks masks) |
| 312 | +{ |
| 313 | + const union access_masks_all masks_all = { |
| 314 | + .masks = masks, |
| 315 | + }; |
| 316 | + union access_masks_all merge = {}; |
| 317 | + |
| 318 | + if (!domain) |
| 319 | + return NULL; |
| 320 | + |
| 321 | + merge.masks = landlock_union_access_masks(domain); |
| 322 | + if (merge.all & masks_all.all) |
| 323 | + return domain; |
| 324 | + |
| 325 | + return NULL; |
| 326 | +} |
| 327 | + |
263 | 328 | static inline void
|
264 | 329 | landlock_add_fs_access_mask(struct landlock_ruleset *const ruleset,
|
265 | 330 | const access_mask_t fs_access_mask,
|
@@ -295,19 +360,12 @@ landlock_add_scope_mask(struct landlock_ruleset *const ruleset,
|
295 | 360 | ruleset->access_masks[layer_level].scope |= mask;
|
296 | 361 | }
|
297 | 362 |
|
298 |
| -static inline access_mask_t |
299 |
| -landlock_get_raw_fs_access_mask(const struct landlock_ruleset *const ruleset, |
300 |
| - const u16 layer_level) |
301 |
| -{ |
302 |
| - return ruleset->access_masks[layer_level].fs; |
303 |
| -} |
304 |
| - |
305 | 363 | static inline access_mask_t
|
306 | 364 | landlock_get_fs_access_mask(const struct landlock_ruleset *const ruleset,
|
307 | 365 | const u16 layer_level)
|
308 | 366 | {
|
309 | 367 | /* Handles all initially denied by default access rights. */
|
310 |
| - return landlock_get_raw_fs_access_mask(ruleset, layer_level) | |
| 368 | + return ruleset->access_masks[layer_level].fs | |
311 | 369 | LANDLOCK_ACCESS_FS_INITIALLY_DENIED;
|
312 | 370 | }
|
313 | 371 |
|
|
0 commit comments