Skip to content

Commit 6f442d4

Browse files
committed
apparmor: fix profile verification and enable it
The transition table size was not being set by compat mappings resulting in the profile verification code not being run. Unfortunately the checks were also buggy not being correctly updated from the old accept perms, to the new layout. Also indicate to userspace that the kernel has the permstable verification fixes. BugLink: http://bugs.launchpad.net/bugs/2017903 Fixes: 670f317 ("apparmor: verify permission table indexes") Signed-off-by: John Johansen <[email protected]> Reviewed-by: Jon Tourville <[email protected]>
1 parent 0bac200 commit 6f442d4

File tree

2 files changed

+27
-25
lines changed

2 files changed

+27
-25
lines changed

security/apparmor/policy_compat.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ static struct aa_perms compute_fperms_other(struct aa_dfa *dfa,
146146
*
147147
* Returns: remapped perm table
148148
*/
149-
static struct aa_perms *compute_fperms(struct aa_dfa *dfa)
149+
static struct aa_perms *compute_fperms(struct aa_dfa *dfa,
150+
u32 *size)
150151
{
151152
aa_state_t state;
152153
unsigned int state_count;
@@ -159,6 +160,7 @@ static struct aa_perms *compute_fperms(struct aa_dfa *dfa)
159160
table = kvcalloc(state_count * 2, sizeof(struct aa_perms), GFP_KERNEL);
160161
if (!table)
161162
return NULL;
163+
*size = state_count * 2;
162164

163165
/* zero init so skip the trap state (state == 0) */
164166
for (state = 1; state < state_count; state++) {
@@ -169,7 +171,8 @@ static struct aa_perms *compute_fperms(struct aa_dfa *dfa)
169171
return table;
170172
}
171173

172-
static struct aa_perms *compute_xmatch_perms(struct aa_dfa *xmatch)
174+
static struct aa_perms *compute_xmatch_perms(struct aa_dfa *xmatch,
175+
u32 *size)
173176
{
174177
struct aa_perms *perms;
175178
int state;
@@ -182,6 +185,7 @@ static struct aa_perms *compute_xmatch_perms(struct aa_dfa *xmatch)
182185
perms = kvcalloc(state_count, sizeof(struct aa_perms), GFP_KERNEL);
183186
if (!perms)
184187
return NULL;
188+
*size = state_count;
185189

186190
/* zero init so skip the trap state (state == 0) */
187191
for (state = 1; state < state_count; state++)
@@ -242,7 +246,8 @@ static struct aa_perms compute_perms_entry(struct aa_dfa *dfa,
242246
return perms;
243247
}
244248

245-
static struct aa_perms *compute_perms(struct aa_dfa *dfa, u32 version)
249+
static struct aa_perms *compute_perms(struct aa_dfa *dfa, u32 version,
250+
u32 *size)
246251
{
247252
unsigned int state;
248253
unsigned int state_count;
@@ -255,6 +260,7 @@ static struct aa_perms *compute_perms(struct aa_dfa *dfa, u32 version)
255260
table = kvcalloc(state_count, sizeof(struct aa_perms), GFP_KERNEL);
256261
if (!table)
257262
return NULL;
263+
*size = state_count;
258264

259265
/* zero init so skip the trap state (state == 0) */
260266
for (state = 1; state < state_count; state++)
@@ -289,7 +295,7 @@ static void remap_dfa_accept(struct aa_dfa *dfa, unsigned int factor)
289295
/* TODO: merge different dfa mappings into single map_policy fn */
290296
int aa_compat_map_xmatch(struct aa_policydb *policy)
291297
{
292-
policy->perms = compute_xmatch_perms(policy->dfa);
298+
policy->perms = compute_xmatch_perms(policy->dfa, &policy->size);
293299
if (!policy->perms)
294300
return -ENOMEM;
295301

@@ -300,7 +306,7 @@ int aa_compat_map_xmatch(struct aa_policydb *policy)
300306

301307
int aa_compat_map_policy(struct aa_policydb *policy, u32 version)
302308
{
303-
policy->perms = compute_perms(policy->dfa, version);
309+
policy->perms = compute_perms(policy->dfa, version, &policy->size);
304310
if (!policy->perms)
305311
return -ENOMEM;
306312

@@ -311,7 +317,7 @@ int aa_compat_map_policy(struct aa_policydb *policy, u32 version)
311317

312318
int aa_compat_map_file(struct aa_policydb *policy)
313319
{
314-
policy->perms = compute_fperms(policy->dfa);
320+
policy->perms = compute_fperms(policy->dfa, &policy->size);
315321
if (!policy->perms)
316322
return -ENOMEM;
317323

security/apparmor/policy_unpack.c

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,22 +1135,16 @@ static int verify_header(struct aa_ext *e, int required, const char **ns)
11351135
return 0;
11361136
}
11371137

1138-
static bool verify_xindex(int xindex, int table_size)
1139-
{
1140-
int index, xtype;
1141-
xtype = xindex & AA_X_TYPE_MASK;
1142-
index = xindex & AA_X_INDEX_MASK;
1143-
if (xtype == AA_X_TABLE && index >= table_size)
1144-
return false;
1145-
return true;
1146-
}
1147-
1148-
/* verify dfa xindexes are in range of transition tables */
1149-
static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
1138+
/**
1139+
* verify_dfa_accept_xindex - verify accept indexes are in range of perms table
1140+
* @dfa: the dfa to check accept indexes are in range
1141+
* table_size: the permission table size the indexes should be within
1142+
*/
1143+
static bool verify_dfa_accept_index(struct aa_dfa *dfa, int table_size)
11501144
{
11511145
int i;
11521146
for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
1153-
if (!verify_xindex(ACCEPT_TABLE(dfa)[i], table_size))
1147+
if (ACCEPT_TABLE(dfa)[i] >= table_size)
11541148
return false;
11551149
}
11561150
return true;
@@ -1187,11 +1181,13 @@ static bool verify_perms(struct aa_policydb *pdb)
11871181
if (!verify_perm(&pdb->perms[i]))
11881182
return false;
11891183
/* verify indexes into str table */
1190-
if (pdb->perms[i].xindex >= pdb->trans.size)
1184+
if ((pdb->perms[i].xindex & AA_X_TYPE_MASK) == AA_X_TABLE &&
1185+
(pdb->perms[i].xindex & AA_X_INDEX_MASK) >= pdb->trans.size)
11911186
return false;
1192-
if (pdb->perms[i].tag >= pdb->trans.size)
1187+
if (pdb->perms[i].tag && pdb->perms[i].tag >= pdb->trans.size)
11931188
return false;
1194-
if (pdb->perms[i].label >= pdb->trans.size)
1189+
if (pdb->perms[i].label &&
1190+
pdb->perms[i].label >= pdb->trans.size)
11951191
return false;
11961192
}
11971193

@@ -1213,10 +1209,10 @@ static int verify_profile(struct aa_profile *profile)
12131209
if (!rules)
12141210
return 0;
12151211

1216-
if ((rules->file.dfa && !verify_dfa_xindex(rules->file.dfa,
1217-
rules->file.trans.size)) ||
1212+
if ((rules->file.dfa && !verify_dfa_accept_index(rules->file.dfa,
1213+
rules->file.size)) ||
12181214
(rules->policy.dfa &&
1219-
!verify_dfa_xindex(rules->policy.dfa, rules->policy.trans.size))) {
1215+
!verify_dfa_accept_index(rules->policy.dfa, rules->policy.size))) {
12201216
audit_iface(profile, NULL, NULL,
12211217
"Unpack: Invalid named transition", NULL, -EPROTO);
12221218
return -EPROTO;

0 commit comments

Comments
 (0)