@@ -300,36 +300,22 @@ static void put_hierarchy(struct landlock_hierarchy *hierarchy)
300
300
}
301
301
}
302
302
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 )
305
306
{
306
307
struct landlock_rule * walker_rule , * next_rule ;
307
308
struct rb_root * src_root ;
308
309
int err = 0 ;
309
310
310
311
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 );
317
314
318
- src_root = get_root (src , LANDLOCK_KEY_INODE );
315
+ src_root = get_root (src , key_type );
319
316
if (IS_ERR (src_root ))
320
317
return PTR_ERR (src_root );
321
318
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
-
333
319
/* Merges the @src tree. */
334
320
rbtree_postorder_for_each_entry_safe (walker_rule , next_rule , src_root ,
335
321
node ) {
@@ -338,62 +324,108 @@ static int merge_ruleset(struct landlock_ruleset *const dst,
338
324
} };
339
325
const struct landlock_id id = {
340
326
.key = walker_rule -> key ,
341
- .type = LANDLOCK_KEY_INODE ,
327
+ .type = key_type ,
342
328
};
343
329
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
+
352
336
layers [0 ].access = walker_rule -> layers [0 ].access ;
353
337
354
338
err = insert_rule (dst , id , & layers , ARRAY_SIZE (layers ));
355
339
if (err )
356
- goto out_unlock ;
340
+ return err ;
357
341
}
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 ;
358
373
359
374
out_unlock :
360
375
mutex_unlock (& src -> lock );
361
376
mutex_unlock (& dst -> lock );
362
377
return err ;
363
378
}
364
379
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 )
367
383
{
368
384
struct landlock_rule * walker_rule , * next_rule ;
369
385
struct rb_root * parent_root ;
370
386
int err = 0 ;
371
387
372
388
might_sleep ();
373
- if (! parent )
374
- return 0 ;
389
+ lockdep_assert_held ( & parent -> lock );
390
+ lockdep_assert_held ( & child -> lock ) ;
375
391
376
- parent_root = get_root (parent , LANDLOCK_KEY_INODE );
392
+ parent_root = get_root (parent , key_type );
377
393
if (IS_ERR (parent_root ))
378
394
return PTR_ERR (parent_root );
379
395
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. */
385
397
rbtree_postorder_for_each_entry_safe (walker_rule , next_rule ,
386
398
parent_root , node ) {
387
399
const struct landlock_id id = {
388
400
.key = walker_rule -> key ,
389
- .type = LANDLOCK_KEY_INODE ,
401
+ .type = key_type ,
390
402
};
391
403
392
404
err = insert_rule (child , id , & walker_rule -> layers ,
393
405
walker_rule -> num_layers );
394
406
if (err )
395
- goto out_unlock ;
407
+ return err ;
396
408
}
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 ;
397
429
398
430
if (WARN_ON_ONCE (child -> num_layers <= parent -> num_layers )) {
399
431
err = - EINVAL ;
0 commit comments