@@ -317,6 +317,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
317
317
318
318
if (!bprm || !profile -> xattr_count )
319
319
return 0 ;
320
+ might_sleep ();
320
321
321
322
/* transition from exec match to xattr set */
322
323
state = aa_dfa_null_transition (profile -> xmatch , state );
@@ -361,10 +362,11 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
361
362
}
362
363
363
364
/**
364
- * __attach_match_ - find an attachment match
365
+ * find_attach - do attachment search for unconfined processes
365
366
* @bprm - binprm structure of transitioning task
366
- * @name - to match against (NOT NULL)
367
+ * @ns: the current namespace (NOT NULL)
367
368
* @head - profile list to walk (NOT NULL)
369
+ * @name - to match against (NOT NULL)
368
370
* @info - info message if there was an error (NOT NULL)
369
371
*
370
372
* Do a linear search on the profiles in the list. There is a matching
@@ -374,12 +376,11 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
374
376
*
375
377
* Requires: @head not be shared or have appropriate locks held
376
378
*
377
- * Returns: profile or NULL if no match found
379
+ * Returns: label or NULL if no match found
378
380
*/
379
- static struct aa_profile * __attach_match (const struct linux_binprm * bprm ,
380
- const char * name ,
381
- struct list_head * head ,
382
- const char * * info )
381
+ static struct aa_label * find_attach (const struct linux_binprm * bprm ,
382
+ struct aa_ns * ns , struct list_head * head ,
383
+ const char * name , const char * * info )
383
384
{
384
385
int candidate_len = 0 , candidate_xattrs = 0 ;
385
386
bool conflict = false;
@@ -388,6 +389,8 @@ static struct aa_profile *__attach_match(const struct linux_binprm *bprm,
388
389
AA_BUG (!name );
389
390
AA_BUG (!head );
390
391
392
+ rcu_read_lock ();
393
+ restart :
391
394
list_for_each_entry_rcu (profile , head , base .list ) {
392
395
if (profile -> label .flags & FLAG_NULL &&
393
396
& profile -> label == ns_unconfined (profile -> ns ))
@@ -413,16 +416,32 @@ static struct aa_profile *__attach_match(const struct linux_binprm *bprm,
413
416
perm = dfa_user_allow (profile -> xmatch , state );
414
417
/* any accepting state means a valid match. */
415
418
if (perm & MAY_EXEC ) {
416
- int ret ;
419
+ int ret = 0 ;
417
420
418
421
if (count < candidate_len )
419
422
continue ;
420
423
421
- ret = aa_xattrs_match (bprm , profile , state );
422
- /* Fail matching if the xattrs don't match */
423
- if (ret < 0 )
424
- continue ;
425
-
424
+ if (bprm && profile -> xattr_count ) {
425
+ long rev = READ_ONCE (ns -> revision );
426
+
427
+ if (!aa_get_profile_not0 (profile ))
428
+ goto restart ;
429
+ rcu_read_unlock ();
430
+ ret = aa_xattrs_match (bprm , profile ,
431
+ state );
432
+ rcu_read_lock ();
433
+ aa_put_profile (profile );
434
+ if (rev !=
435
+ READ_ONCE (ns -> revision ))
436
+ /* policy changed */
437
+ goto restart ;
438
+ /*
439
+ * Fail matching if the xattrs don't
440
+ * match
441
+ */
442
+ if (ret < 0 )
443
+ continue ;
444
+ }
426
445
/*
427
446
* TODO: allow for more flexible best match
428
447
*
@@ -445,43 +464,28 @@ static struct aa_profile *__attach_match(const struct linux_binprm *bprm,
445
464
candidate_xattrs = ret ;
446
465
conflict = false;
447
466
}
448
- } else if (!strcmp (profile -> base .name , name ))
467
+ } else if (!strcmp (profile -> base .name , name )) {
449
468
/*
450
469
* old exact non-re match, without conditionals such
451
470
* as xattrs. no more searching required
452
471
*/
453
- return profile ;
472
+ candidate = profile ;
473
+ goto out ;
474
+ }
454
475
}
455
476
456
- if (conflict ) {
457
- * info = "conflicting profile attachments" ;
477
+ if (!candidate || conflict ) {
478
+ if (conflict )
479
+ * info = "conflicting profile attachments" ;
480
+ rcu_read_unlock ();
458
481
return NULL ;
459
482
}
460
483
461
- return candidate ;
462
- }
463
-
464
- /**
465
- * find_attach - do attachment search for unconfined processes
466
- * @bprm - binprm structure of transitioning task
467
- * @ns: the current namespace (NOT NULL)
468
- * @list: list to search (NOT NULL)
469
- * @name: the executable name to match against (NOT NULL)
470
- * @info: info message if there was an error
471
- *
472
- * Returns: label or NULL if no match found
473
- */
474
- static struct aa_label * find_attach (const struct linux_binprm * bprm ,
475
- struct aa_ns * ns , struct list_head * list ,
476
- const char * name , const char * * info )
477
- {
478
- struct aa_profile * profile ;
479
-
480
- rcu_read_lock ();
481
- profile = aa_get_profile (__attach_match (bprm , name , list , info ));
484
+ out :
485
+ candidate = aa_get_newest_profile (candidate );
482
486
rcu_read_unlock ();
483
487
484
- return profile ? & profile -> label : NULL ;
488
+ return & candidate -> label ;
485
489
}
486
490
487
491
static const char * next_name (int xtype , const char * name )
0 commit comments