Skip to content

Commit 6146b61

Browse files
BoardzMasterl0kod
authored andcommitted
landlock: Refactor merge/inherit_ruleset helpers
Refactor merge_ruleset() and inherit_ruleset() functions to support new rule types. Add merge_tree() and inherit_tree() helpers. They use a specific ruleset's red-black tree according to a key type argument. Signed-off-by: Konstantin Meskhidze <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mickaël Salaün <[email protected]>
1 parent a4ac404 commit 6146b61

File tree

1 file changed

+74
-42
lines changed

1 file changed

+74
-42
lines changed

security/landlock/ruleset.c

Lines changed: 74 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -300,36 +300,22 @@ static void put_hierarchy(struct landlock_hierarchy *hierarchy)
300300
}
301301
}
302302

303-
static int merge_ruleset(struct landlock_ruleset *const dst,
304-
struct landlock_ruleset *const src)
303+
static int merge_tree(struct landlock_ruleset *const dst,
304+
struct landlock_ruleset *const src,
305+
const enum landlock_key_type key_type)
305306
{
306307
struct landlock_rule *walker_rule, *next_rule;
307308
struct rb_root *src_root;
308309
int err = 0;
309310

310311
might_sleep();
311-
/* Should already be checked by landlock_merge_ruleset() */
312-
if (WARN_ON_ONCE(!src))
313-
return 0;
314-
/* Only merge into a domain. */
315-
if (WARN_ON_ONCE(!dst || !dst->hierarchy))
316-
return -EINVAL;
312+
lockdep_assert_held(&dst->lock);
313+
lockdep_assert_held(&src->lock);
317314

318-
src_root = get_root(src, LANDLOCK_KEY_INODE);
315+
src_root = get_root(src, key_type);
319316
if (IS_ERR(src_root))
320317
return PTR_ERR(src_root);
321318

322-
/* Locks @dst first because we are its only owner. */
323-
mutex_lock(&dst->lock);
324-
mutex_lock_nested(&src->lock, SINGLE_DEPTH_NESTING);
325-
326-
/* Stacks the new layer. */
327-
if (WARN_ON_ONCE(src->num_layers != 1 || dst->num_layers < 1)) {
328-
err = -EINVAL;
329-
goto out_unlock;
330-
}
331-
dst->access_masks[dst->num_layers - 1] = src->access_masks[0];
332-
333319
/* Merges the @src tree. */
334320
rbtree_postorder_for_each_entry_safe(walker_rule, next_rule, src_root,
335321
node) {
@@ -338,62 +324,108 @@ static int merge_ruleset(struct landlock_ruleset *const dst,
338324
} };
339325
const struct landlock_id id = {
340326
.key = walker_rule->key,
341-
.type = LANDLOCK_KEY_INODE,
327+
.type = key_type,
342328
};
343329

344-
if (WARN_ON_ONCE(walker_rule->num_layers != 1)) {
345-
err = -EINVAL;
346-
goto out_unlock;
347-
}
348-
if (WARN_ON_ONCE(walker_rule->layers[0].level != 0)) {
349-
err = -EINVAL;
350-
goto out_unlock;
351-
}
330+
if (WARN_ON_ONCE(walker_rule->num_layers != 1))
331+
return -EINVAL;
332+
333+
if (WARN_ON_ONCE(walker_rule->layers[0].level != 0))
334+
return -EINVAL;
335+
352336
layers[0].access = walker_rule->layers[0].access;
353337

354338
err = insert_rule(dst, id, &layers, ARRAY_SIZE(layers));
355339
if (err)
356-
goto out_unlock;
340+
return err;
357341
}
342+
return err;
343+
}
344+
345+
static int merge_ruleset(struct landlock_ruleset *const dst,
346+
struct landlock_ruleset *const src)
347+
{
348+
int err = 0;
349+
350+
might_sleep();
351+
/* Should already be checked by landlock_merge_ruleset() */
352+
if (WARN_ON_ONCE(!src))
353+
return 0;
354+
/* Only merge into a domain. */
355+
if (WARN_ON_ONCE(!dst || !dst->hierarchy))
356+
return -EINVAL;
357+
358+
/* Locks @dst first because we are its only owner. */
359+
mutex_lock(&dst->lock);
360+
mutex_lock_nested(&src->lock, SINGLE_DEPTH_NESTING);
361+
362+
/* Stacks the new layer. */
363+
if (WARN_ON_ONCE(src->num_layers != 1 || dst->num_layers < 1)) {
364+
err = -EINVAL;
365+
goto out_unlock;
366+
}
367+
dst->access_masks[dst->num_layers - 1] = src->access_masks[0];
368+
369+
/* Merges the @src inode tree. */
370+
err = merge_tree(dst, src, LANDLOCK_KEY_INODE);
371+
if (err)
372+
goto out_unlock;
358373

359374
out_unlock:
360375
mutex_unlock(&src->lock);
361376
mutex_unlock(&dst->lock);
362377
return err;
363378
}
364379

365-
static int inherit_ruleset(struct landlock_ruleset *const parent,
366-
struct landlock_ruleset *const child)
380+
static int inherit_tree(struct landlock_ruleset *const parent,
381+
struct landlock_ruleset *const child,
382+
const enum landlock_key_type key_type)
367383
{
368384
struct landlock_rule *walker_rule, *next_rule;
369385
struct rb_root *parent_root;
370386
int err = 0;
371387

372388
might_sleep();
373-
if (!parent)
374-
return 0;
389+
lockdep_assert_held(&parent->lock);
390+
lockdep_assert_held(&child->lock);
375391

376-
parent_root = get_root(parent, LANDLOCK_KEY_INODE);
392+
parent_root = get_root(parent, key_type);
377393
if (IS_ERR(parent_root))
378394
return PTR_ERR(parent_root);
379395

380-
/* Locks @child first because we are its only owner. */
381-
mutex_lock(&child->lock);
382-
mutex_lock_nested(&parent->lock, SINGLE_DEPTH_NESTING);
383-
384-
/* Copies the @parent tree. */
396+
/* Copies the @parent inode or network tree. */
385397
rbtree_postorder_for_each_entry_safe(walker_rule, next_rule,
386398
parent_root, node) {
387399
const struct landlock_id id = {
388400
.key = walker_rule->key,
389-
.type = LANDLOCK_KEY_INODE,
401+
.type = key_type,
390402
};
391403

392404
err = insert_rule(child, id, &walker_rule->layers,
393405
walker_rule->num_layers);
394406
if (err)
395-
goto out_unlock;
407+
return err;
396408
}
409+
return err;
410+
}
411+
412+
static int inherit_ruleset(struct landlock_ruleset *const parent,
413+
struct landlock_ruleset *const child)
414+
{
415+
int err = 0;
416+
417+
might_sleep();
418+
if (!parent)
419+
return 0;
420+
421+
/* Locks @child first because we are its only owner. */
422+
mutex_lock(&child->lock);
423+
mutex_lock_nested(&parent->lock, SINGLE_DEPTH_NESTING);
424+
425+
/* Copies the @parent inode tree. */
426+
err = inherit_tree(parent, child, LANDLOCK_KEY_INODE);
427+
if (err)
428+
goto out_unlock;
397429

398430
if (WARN_ON_ONCE(child->num_layers <= parent->num_layers)) {
399431
err = -EINVAL;

0 commit comments

Comments
 (0)