@@ -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
359374out_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