@@ -309,169 +309,6 @@ int landlock_insert_rule(struct landlock_ruleset *const ruleset,
309309 return insert_rule (ruleset , id , & layers , ARRAY_SIZE (layers ));
310310}
311311
312- static int merge_tree (struct landlock_ruleset * const dst ,
313- struct landlock_ruleset * const src ,
314- const enum landlock_key_type key_type )
315- {
316- struct landlock_rule * walker_rule , * next_rule ;
317- struct rb_root * src_root ;
318- int err = 0 ;
319-
320- might_sleep ();
321- lockdep_assert_held (& dst -> lock );
322- lockdep_assert_held (& src -> lock );
323-
324- src_root = get_root (src , key_type );
325- if (IS_ERR (src_root ))
326- return PTR_ERR (src_root );
327-
328- /* Merges the @src tree. */
329- rbtree_postorder_for_each_entry_safe (walker_rule , next_rule , src_root ,
330- node ) {
331- struct landlock_layer layers [] = { {
332- .level = dst -> num_layers ,
333- } };
334- const struct landlock_id id = {
335- .key = walker_rule -> key ,
336- .type = key_type ,
337- };
338-
339- if (WARN_ON_ONCE (walker_rule -> num_layers != 1 ))
340- return - EINVAL ;
341-
342- if (WARN_ON_ONCE (walker_rule -> layers [0 ].level != 0 ))
343- return - EINVAL ;
344-
345- layers [0 ].access = walker_rule -> layers [0 ].access ;
346-
347- err = insert_rule (dst , id , & layers , ARRAY_SIZE (layers ));
348- if (err )
349- return err ;
350- }
351- return err ;
352- }
353-
354- static int merge_ruleset (struct landlock_ruleset * const dst ,
355- struct landlock_ruleset * const src )
356- {
357- int err = 0 ;
358-
359- might_sleep ();
360- /* Should already be checked by landlock_merge_ruleset() */
361- if (WARN_ON_ONCE (!src ))
362- return 0 ;
363- /* Only merge into a domain. */
364- if (WARN_ON_ONCE (!dst || !dst -> hierarchy ))
365- return - EINVAL ;
366-
367- /* Locks @dst first because we are its only owner. */
368- mutex_lock (& dst -> lock );
369- mutex_lock_nested (& src -> lock , SINGLE_DEPTH_NESTING );
370-
371- /* Stacks the new layer. */
372- if (WARN_ON_ONCE (src -> num_layers != 1 || dst -> num_layers < 1 )) {
373- err = - EINVAL ;
374- goto out_unlock ;
375- }
376- dst -> access_masks [dst -> num_layers - 1 ] =
377- landlock_upgrade_handled_access_masks (src -> access_masks [0 ]);
378-
379- /* Merges the @src inode tree. */
380- err = merge_tree (dst , src , LANDLOCK_KEY_INODE );
381- if (err )
382- goto out_unlock ;
383-
384- #if IS_ENABLED (CONFIG_INET )
385- /* Merges the @src network port tree. */
386- err = merge_tree (dst , src , LANDLOCK_KEY_NET_PORT );
387- if (err )
388- goto out_unlock ;
389- #endif /* IS_ENABLED(CONFIG_INET) */
390-
391- out_unlock :
392- mutex_unlock (& src -> lock );
393- mutex_unlock (& dst -> lock );
394- return err ;
395- }
396-
397- static int inherit_tree (struct landlock_ruleset * const parent ,
398- struct landlock_ruleset * const child ,
399- const enum landlock_key_type key_type )
400- {
401- struct landlock_rule * walker_rule , * next_rule ;
402- struct rb_root * parent_root ;
403- int err = 0 ;
404-
405- might_sleep ();
406- lockdep_assert_held (& parent -> lock );
407- lockdep_assert_held (& child -> lock );
408-
409- parent_root = get_root (parent , key_type );
410- if (IS_ERR (parent_root ))
411- return PTR_ERR (parent_root );
412-
413- /* Copies the @parent inode or network tree. */
414- rbtree_postorder_for_each_entry_safe (walker_rule , next_rule ,
415- parent_root , node ) {
416- const struct landlock_id id = {
417- .key = walker_rule -> key ,
418- .type = key_type ,
419- };
420-
421- err = insert_rule (child , id , & walker_rule -> layers ,
422- walker_rule -> num_layers );
423- if (err )
424- return err ;
425- }
426- return err ;
427- }
428-
429- static int inherit_ruleset (struct landlock_ruleset * const parent ,
430- struct landlock_ruleset * const child )
431- {
432- int err = 0 ;
433-
434- might_sleep ();
435- if (!parent )
436- return 0 ;
437-
438- /* Locks @child first because we are its only owner. */
439- mutex_lock (& child -> lock );
440- mutex_lock_nested (& parent -> lock , SINGLE_DEPTH_NESTING );
441-
442- /* Copies the @parent inode tree. */
443- err = inherit_tree (parent , child , LANDLOCK_KEY_INODE );
444- if (err )
445- goto out_unlock ;
446-
447- #if IS_ENABLED (CONFIG_INET )
448- /* Copies the @parent network port tree. */
449- err = inherit_tree (parent , child , LANDLOCK_KEY_NET_PORT );
450- if (err )
451- goto out_unlock ;
452- #endif /* IS_ENABLED(CONFIG_INET) */
453-
454- if (WARN_ON_ONCE (child -> num_layers <= parent -> num_layers )) {
455- err = - EINVAL ;
456- goto out_unlock ;
457- }
458- /* Copies the parent layer stack and leaves a space for the new layer. */
459- memcpy (child -> access_masks , parent -> access_masks ,
460- flex_array_size (parent , access_masks , parent -> num_layers ));
461-
462- if (WARN_ON_ONCE (!parent -> hierarchy )) {
463- err = - EINVAL ;
464- goto out_unlock ;
465- }
466- landlock_get_hierarchy (parent -> hierarchy );
467- child -> hierarchy -> parent = parent -> hierarchy ;
468-
469- out_unlock :
470- mutex_unlock (& parent -> lock );
471- mutex_unlock (& child -> lock );
472- return err ;
473- }
474-
475312static void free_ruleset (struct landlock_ruleset * const ruleset )
476313{
477314 struct landlock_rule * freeme , * next ;
@@ -515,67 +352,6 @@ void landlock_put_ruleset_deferred(struct landlock_ruleset *const ruleset)
515352 }
516353}
517354
518- /**
519- * landlock_merge_ruleset - Merge a ruleset with a domain
520- *
521- * @parent: Parent domain.
522- * @ruleset: New ruleset to be merged.
523- *
524- * The current task is requesting to be restricted. The subjective credentials
525- * must not be in an overridden state. cf. landlock_init_hierarchy_log().
526- *
527- * Returns the intersection of @parent and @ruleset, or returns @parent if
528- * @ruleset is empty, or returns a duplicate of @ruleset if @parent is empty.
529- */
530- struct landlock_ruleset *
531- landlock_merge_ruleset (struct landlock_ruleset * const parent ,
532- struct landlock_ruleset * const ruleset )
533- {
534- struct landlock_ruleset * new_dom __free (landlock_put_ruleset ) = NULL ;
535- u32 num_layers ;
536- int err ;
537-
538- might_sleep ();
539- if (WARN_ON_ONCE (!ruleset || parent == ruleset ))
540- return ERR_PTR (- EINVAL );
541-
542- if (parent ) {
543- if (parent -> num_layers >= LANDLOCK_MAX_NUM_LAYERS )
544- return ERR_PTR (- E2BIG );
545- num_layers = parent -> num_layers + 1 ;
546- } else {
547- num_layers = 1 ;
548- }
549-
550- /* Creates a new domain... */
551- new_dom = create_ruleset (num_layers );
552- if (IS_ERR (new_dom ))
553- return new_dom ;
554-
555- new_dom -> hierarchy =
556- kzalloc (sizeof (* new_dom -> hierarchy ), GFP_KERNEL_ACCOUNT );
557- if (!new_dom -> hierarchy )
558- return ERR_PTR (- ENOMEM );
559-
560- refcount_set (& new_dom -> hierarchy -> usage , 1 );
561-
562- /* ...as a child of @parent... */
563- err = inherit_ruleset (parent , new_dom );
564- if (err )
565- return ERR_PTR (err );
566-
567- /* ...and including @ruleset. */
568- err = merge_ruleset (new_dom , ruleset );
569- if (err )
570- return ERR_PTR (err );
571-
572- err = landlock_init_hierarchy_log (new_dom -> hierarchy );
573- if (err )
574- return ERR_PTR (err );
575-
576- return no_free_ptr (new_dom );
577- }
578-
579355/*
580356 * The returned access has the same lifetime as @ruleset.
581357 */
0 commit comments