Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

apparmor: in preparation for finer networking rules rework match_prot

Rework match_prot into a common fn that can be shared by all the
networking rules. This will provide compatibility with current socket
mediation, via the early bailout permission encoding.

Signed-off-by: John Johansen <john.johansen@canonical.com>

+75 -14
+6 -2
security/apparmor/include/net.h
··· 82 82 83 83 extern struct aa_sfs_entry aa_sfs_entry_network[]; 84 84 85 + /* passing in state returned by XXX_mediates(class) */ 86 + aa_state_t aa_match_to_prot(struct aa_policydb *policy, aa_state_t state, 87 + u32 request, u16 family, int type, int protocol, 88 + struct aa_perms **p, const char **info); 85 89 void audit_net_cb(struct audit_buffer *ab, void *va); 86 90 int aa_profile_af_perm(struct aa_profile *profile, 87 91 struct apparmor_audit_data *ad, 88 - u32 request, u16 family, int type); 92 + u32 request, u16 family, int type, int protocol); 89 93 int aa_af_perm(const struct cred *subj_cred, struct aa_label *label, 90 94 const char *op, u32 request, u16 family, 91 95 int type, int protocol); ··· 99 95 struct sock *sk) 100 96 { 101 97 return aa_profile_af_perm(profile, ad, request, sk->sk_family, 102 - sk->sk_type); 98 + sk->sk_type, sk->sk_protocol); 103 99 } 104 100 int aa_sk_perm(const char *op, u32 request, struct sock *sk); 105 101
+69 -12
security/apparmor/net.c
··· 105 105 } 106 106 } 107 107 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 + 108 171 /* Generic af perm */ 109 172 int aa_profile_af_perm(struct aa_profile *profile, 110 173 struct apparmor_audit_data *ad, u32 request, u16 family, 111 - int type) 174 + int type, int protocol) 112 175 { 113 176 struct aa_ruleset *rules = list_first_entry(&profile->rules, 114 177 typeof(*rules), list); 115 - struct aa_perms perms = { }; 178 + struct aa_perms *p = NULL; 116 179 aa_state_t state; 117 - __be16 buffer[2]; 118 180 119 181 AA_BUG(family >= AF_MAX); 120 182 AA_BUG(type < 0 || type >= SOCK_MAX); ··· 186 124 if (!state) 187 125 return 0; 188 126 189 - buffer[0] = cpu_to_be16(family); 190 - buffer[1] = cpu_to_be16((u16) type); 191 - state = aa_dfa_match_len(rules->policy->dfa, state, (char *) &buffer, 192 - 4); 193 - perms = *aa_lookup_perms(rules->policy, state); 194 - aa_apply_modes_to_perms(profile, &perms); 195 - 196 - return aa_check_perms(profile, &perms, request, ad, audit_net_cb); 127 + state = aa_match_to_prot(rules->policy, state, request, family, type, 128 + protocol, &p, &ad->info); 129 + return do_perms(profile, rules->policy, state, request, p, ad); 197 130 } 198 131 199 132 int aa_af_perm(const struct cred *subj_cred, struct aa_label *label, ··· 199 142 200 143 return fn_for_each_confined(label, profile, 201 144 aa_profile_af_perm(profile, &ad, request, family, 202 - type)); 145 + type, protocol)); 203 146 } 204 147 205 148 static int aa_label_sk_perm(const struct cred *subj_cred,