@@ -105,16 +105,78 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
105105 }
106106}
107107
108+ /* standard permission lookup pattern - supports early bailout */
109+ static int do_perms (struct aa_profile * profile , struct aa_policydb * policy ,
110+ unsigned int state , u32 request ,
111+ struct aa_perms * p , struct apparmor_audit_data * ad )
112+ {
113+ struct aa_perms perms ;
114+
115+ AA_BUG (!profile );
116+ AA_BUG (!policy );
117+
118+
119+ if (state || !p )
120+ p = aa_lookup_perms (policy , state );
121+ perms = * p ;
122+ aa_apply_modes_to_perms (profile , & perms );
123+ return aa_check_perms (profile , & perms , request , ad ,
124+ audit_net_cb );
125+ }
126+
127+ /* only continue match if
128+ * insufficient current perms at current state
129+ * indicates there are more perms in later state
130+ * Returns: perms struct if early match
131+ */
132+ static struct aa_perms * early_match (struct aa_policydb * policy ,
133+ aa_state_t state , u32 request )
134+ {
135+ struct aa_perms * p ;
136+
137+ p = aa_lookup_perms (policy , state );
138+ if (((p -> allow & request ) != request ) && (p -> allow & AA_CONT_MATCH ))
139+ return NULL ;
140+ return p ;
141+ }
142+
143+ /* passing in state returned by PROFILE_MEDIATES_AF */
144+ aa_state_t aa_match_to_prot (struct aa_policydb * policy , aa_state_t state ,
145+ u32 request , u16 family , int type , int protocol ,
146+ struct aa_perms * * p , const char * * info )
147+ {
148+ __be16 buffer ;
149+
150+ buffer = cpu_to_be16 (family );
151+ state = aa_dfa_match_len (policy -> dfa , state , (char * ) & buffer , 2 );
152+ if (!state ) {
153+ * info = "failed af match" ;
154+ return DFA_NOMATCH ;
155+ }
156+ buffer = cpu_to_be16 ((u16 )type );
157+ state = aa_dfa_match_len (policy -> dfa , state , (char * ) & buffer , 2 );
158+ if (!state )
159+ * info = "failed type match" ;
160+ * p = early_match (policy , state , request );
161+ if (!* p ) {
162+ buffer = cpu_to_be16 ((u16 )protocol );
163+ state = aa_dfa_match_len (policy -> dfa , state , (char * ) & buffer ,
164+ 2 );
165+ if (!state )
166+ * info = "failed protocol match" ;
167+ }
168+ return state ;
169+ }
170+
108171/* Generic af perm */
109172int aa_profile_af_perm (struct aa_profile * profile ,
110173 struct apparmor_audit_data * ad , u32 request , u16 family ,
111- int type )
174+ int type , int protocol )
112175{
113176 struct aa_ruleset * rules = list_first_entry (& profile -> rules ,
114177 typeof (* rules ), list );
115- struct aa_perms perms = { } ;
178+ struct aa_perms * p = NULL ;
116179 aa_state_t state ;
117- __be16 buffer [2 ];
118180
119181 AA_BUG (family >= AF_MAX );
120182 AA_BUG (type < 0 || type >= SOCK_MAX );
@@ -124,14 +186,9 @@ int aa_profile_af_perm(struct aa_profile *profile,
124186 if (!state )
125187 return 0 ;
126188
127- buffer [0 ] = cpu_to_be16 (family );
128- buffer [1 ] = cpu_to_be16 ((u16 ) type );
129- state = aa_dfa_match_len (rules -> policy -> dfa , state , (char * ) & buffer ,
130- 4 );
131- perms = * aa_lookup_perms (rules -> policy , state );
132- aa_apply_modes_to_perms (profile , & perms );
133-
134- return aa_check_perms (profile , & perms , request , ad , audit_net_cb );
189+ state = aa_match_to_prot (rules -> policy , state , request , family , type ,
190+ protocol , & p , & ad -> info );
191+ return do_perms (profile , rules -> policy , state , request , p , ad );
135192}
136193
137194int aa_af_perm (const struct cred * subj_cred , struct aa_label * label ,
@@ -142,7 +199,7 @@ int aa_af_perm(const struct cred *subj_cred, struct aa_label *label,
142199
143200 return fn_for_each_confined (label , profile ,
144201 aa_profile_af_perm (profile , & ad , request , family ,
145- type ));
202+ type , protocol ));
146203}
147204
148205static int aa_label_sk_perm (const struct cred * subj_cred ,
0 commit comments