Skip to content

Commit dcd7a55

Browse files
committed
apparmor: gate make fine grained unix mediation behind v9 abi
Fine grained unix mediation in Ubuntu used ABI v7, and policy using this has propogated onto systems where fine grained unix mediation was not supported. The userspace policy compiler supports downgrading policy so the policy could be shared without changes. Unfortunately this had the side effect that policy was not updated for the none Ubuntu systems and enabling fine grained unix mediation on those systems means that a new kernel can break a system with existing policy that worked with the previous kernel. With fine grained af_unix mediation this regression can easily break the system causing boot to fail, as it affect unix socket files, non-file based unix sockets, and dbus communication. To aoid this regression move fine grained af_unix mediation behind a new abi. This means that the system's userspace and policy must be updated to support the new policy before it takes affect and dropping a new kernel on existing system will not result in a regression. The abi bump is done in such a way as existing policy can be activated on the system by changing the policy abi declaration and existing unix policy rules will apply. Policy then only needs to be incrementally updated, can even be backported to existing Ubuntu policy. Signed-off-by: John Johansen <[email protected]>
1 parent c05e705 commit dcd7a55

File tree

4 files changed

+26
-10
lines changed

4 files changed

+26
-10
lines changed

security/apparmor/af_unix.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ static int profile_create_perm(struct aa_profile *profile, int family,
197197
AA_BUG(!profile);
198198
AA_BUG(profile_unconfined(profile));
199199

200-
state = RULE_MEDIATES_NET(rules);
200+
state = RULE_MEDIATES_v9NET(rules);
201201
if (state) {
202202
state = aa_match_to_prot(rules->policy, state, AA_MAY_CREATE,
203203
PF_UNIX, type, protocol, NULL,
@@ -226,7 +226,7 @@ static int profile_sk_perm(struct aa_profile *profile,
226226
AA_BUG(is_unix_fs(sk));
227227
AA_BUG(profile_unconfined(profile));
228228

229-
state = RULE_MEDIATES_NET(rules);
229+
state = RULE_MEDIATES_v9NET(rules);
230230
if (state) {
231231
state = match_to_sk(rules->policy, state, request, unix_sk(sk),
232232
&p, &ad->info);
@@ -251,7 +251,7 @@ static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
251251
AA_BUG(!ad);
252252
AA_BUG(profile_unconfined(profile));
253253

254-
state = RULE_MEDIATES_NET(rules);
254+
state = RULE_MEDIATES_v9NET(rules);
255255
if (state) {
256256
/* bind for abstract socket */
257257
state = match_to_local(rules->policy, state, AA_MAY_BIND,
@@ -281,7 +281,7 @@ static int profile_listen_perm(struct aa_profile *profile, struct sock *sk,
281281
AA_BUG(!ad);
282282
AA_BUG(profile_unconfined(profile));
283283

284-
state = RULE_MEDIATES_NET(rules);
284+
state = RULE_MEDIATES_v9NET(rules);
285285
if (state) {
286286
__be16 b = cpu_to_be16(backlog);
287287

@@ -315,7 +315,7 @@ static int profile_accept_perm(struct aa_profile *profile,
315315
AA_BUG(!ad);
316316
AA_BUG(profile_unconfined(profile));
317317

318-
state = RULE_MEDIATES_NET(rules);
318+
state = RULE_MEDIATES_v9NET(rules);
319319
if (state) {
320320
state = match_to_sk(rules->policy, state, AA_MAY_ACCEPT,
321321
unix_sk(sk), &p, &ad->info);
@@ -342,7 +342,7 @@ static int profile_opt_perm(struct aa_profile *profile, u32 request,
342342
AA_BUG(!ad);
343343
AA_BUG(profile_unconfined(profile));
344344

345-
state = RULE_MEDIATES_NET(rules);
345+
state = RULE_MEDIATES_v9NET(rules);
346346
if (state) {
347347
__be16 b = cpu_to_be16(optname);
348348

@@ -379,7 +379,7 @@ static int profile_peer_perm(struct aa_profile *profile, u32 request,
379379
AA_BUG(!ad);
380380
AA_BUG(is_unix_fs(peer_sk)); /* currently always calls unix_fs_perm */
381381

382-
state = RULE_MEDIATES_NET(rules);
382+
state = RULE_MEDIATES_v9NET(rules);
383383
if (state) {
384384
struct aa_sk_ctx *peer_ctx = aa_sock(peer_sk);
385385
struct aa_profile *peerp;

security/apparmor/apparmorfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2414,7 +2414,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
24142414
AA_SFS_DIR("domain", aa_sfs_entry_domain),
24152415
AA_SFS_DIR("file", aa_sfs_entry_file),
24162416
AA_SFS_DIR("network_v8", aa_sfs_entry_network),
2417-
AA_SFS_DIR("network", aa_sfs_entry_networkv9),
2417+
AA_SFS_DIR("network_v9", aa_sfs_entry_networkv9),
24182418
AA_SFS_DIR("mount", aa_sfs_entry_mount),
24192419
AA_SFS_DIR("namespaces", aa_sfs_entry_ns),
24202420
AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),

security/apparmor/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ int __aa_path_perm(const char *op, const struct cred *subj_cred,
228228
int e = 0;
229229

230230
if (profile_unconfined(profile) ||
231-
((flags & PATH_SOCK_COND) && !RULE_MEDIATES_NET(rules)))
231+
((flags & PATH_SOCK_COND) && !RULE_MEDIATES_v9NET(rules)))
232232
return 0;
233233
aa_str_perms(rules->file, rules->file->start[AA_CLASS_FILE],
234234
name, cond, perms);

security/apparmor/include/policy.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,27 @@ static inline aa_state_t RULE_MEDIATES(struct aa_ruleset *rules,
304304
rules->policy->start[0], &class, 1);
305305
}
306306

307+
static inline aa_state_t RULE_MEDIATES_v9NET(struct aa_ruleset *rules)
308+
{
309+
return RULE_MEDIATES(rules, AA_CLASS_NETV9);
310+
}
311+
307312
static inline aa_state_t RULE_MEDIATES_NET(struct aa_ruleset *rules)
308313
{
309-
return RULE_MEDIATES(rules, AA_CLASS_NET);
314+
/* can not use RULE_MEDIATE_v9AF here, because AF match fail
315+
* can not be distiguished from class match fail, and we only
316+
* fallback to checking older class on class match failure
317+
*/
318+
aa_state_t state = RULE_MEDIATES(rules, AA_CLASS_NETV9);
319+
320+
/* fallback and check v7/8 if v9 is NOT mediated */
321+
if (!state)
322+
state = RULE_MEDIATES(rules, AA_CLASS_NET);
323+
324+
return state;
310325
}
311326

327+
312328
static inline aa_state_t ANY_RULE_MEDIATES(struct list_head *head,
313329
unsigned char class)
314330
{

0 commit comments

Comments
 (0)