Skip to content

Commit b4940d9

Browse files
committed
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>
1 parent 6cc6a05 commit b4940d9

File tree

2 files changed

+75
-14
lines changed

2 files changed

+75
-14
lines changed

security/apparmor/include/net.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,14 @@ struct aa_secmark {
8282

8383
extern struct aa_sfs_entry aa_sfs_entry_network[];
8484

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);
8589
void audit_net_cb(struct audit_buffer *ab, void *va);
8690
int aa_profile_af_perm(struct aa_profile *profile,
8791
struct apparmor_audit_data *ad,
88-
u32 request, u16 family, int type);
92+
u32 request, u16 family, int type, int protocol);
8993
int aa_af_perm(const struct cred *subj_cred, struct aa_label *label,
9094
const char *op, u32 request, u16 family,
9195
int type, int protocol);
@@ -95,7 +99,7 @@ static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
9599
struct sock *sk)
96100
{
97101
return aa_profile_af_perm(profile, ad, request, sk->sk_family,
98-
sk->sk_type);
102+
sk->sk_type, sk->sk_protocol);
99103
}
100104
int aa_sk_perm(const char *op, u32 request, struct sock *sk);
101105

security/apparmor/net.c

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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 */
109172
int 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

137194
int 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

148205
static int aa_label_sk_perm(const struct cred *subj_cred,

0 commit comments

Comments
 (0)