@@ -317,6 +317,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
317317
318318 if (!bprm || !profile -> xattr_count )
319319 return 0 ;
320+ might_sleep ();
320321
321322 /* transition from exec match to xattr set */
322323 state = aa_dfa_null_transition (profile -> xmatch , state );
@@ -361,10 +362,11 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
361362}
362363
363364/**
364- * __attach_match_ - find an attachment match
365+ * find_attach - do attachment search for unconfined processes
365366 * @bprm - binprm structure of transitioning task
366- * @name - to match against (NOT NULL)
367+ * @ns: the current namespace (NOT NULL)
367368 * @head - profile list to walk (NOT NULL)
369+ * @name - to match against (NOT NULL)
368370 * @info - info message if there was an error (NOT NULL)
369371 *
370372 * 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,
374376 *
375377 * Requires: @head not be shared or have appropriate locks held
376378 *
377- * Returns: profile or NULL if no match found
379+ * Returns: label or NULL if no match found
378380 */
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 )
383384{
384385 int candidate_len = 0 , candidate_xattrs = 0 ;
385386 bool conflict = false;
@@ -388,6 +389,8 @@ static struct aa_profile *__attach_match(const struct linux_binprm *bprm,
388389 AA_BUG (!name );
389390 AA_BUG (!head );
390391
392+ rcu_read_lock ();
393+ restart :
391394 list_for_each_entry_rcu (profile , head , base .list ) {
392395 if (profile -> label .flags & FLAG_NULL &&
393396 & profile -> label == ns_unconfined (profile -> ns ))
@@ -413,16 +416,32 @@ static struct aa_profile *__attach_match(const struct linux_binprm *bprm,
413416 perm = dfa_user_allow (profile -> xmatch , state );
414417 /* any accepting state means a valid match. */
415418 if (perm & MAY_EXEC ) {
416- int ret ;
419+ int ret = 0 ;
417420
418421 if (count < candidate_len )
419422 continue ;
420423
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+ }
426445 /*
427446 * TODO: allow for more flexible best match
428447 *
@@ -445,43 +464,28 @@ static struct aa_profile *__attach_match(const struct linux_binprm *bprm,
445464 candidate_xattrs = ret ;
446465 conflict = false;
447466 }
448- } else if (!strcmp (profile -> base .name , name ))
467+ } else if (!strcmp (profile -> base .name , name )) {
449468 /*
450469 * old exact non-re match, without conditionals such
451470 * as xattrs. no more searching required
452471 */
453- return profile ;
472+ candidate = profile ;
473+ goto out ;
474+ }
454475 }
455476
456- if (conflict ) {
457- * info = "conflicting profile attachments" ;
477+ if (!candidate || conflict ) {
478+ if (conflict )
479+ * info = "conflicting profile attachments" ;
480+ rcu_read_unlock ();
458481 return NULL ;
459482 }
460483
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 );
482486 rcu_read_unlock ();
483487
484- return profile ? & profile -> label : NULL ;
488+ return & candidate -> label ;
485489}
486490
487491static const char * next_name (int xtype , const char * name )
0 commit comments