d = kzalloc(sizeof(*d), GFP_KERNEL); if (d == NULL) return ERR_PTR(-ENOMEM);
d->data = kvzalloc(size, GFP_KERNEL); if (!d->data) {
kfree(d); return ERR_PTR(-ENOMEM);
}
kref_init(&d->count);
INIT_LIST_HEAD(&d->list);
return d;
}
/* test if read will be in packed data bounds */
VISIBLE_IF_KUNIT bool aa_inbounds(struct aa_ext *e, size_t size)
{ return (size <= e->end - e->pos);
}
EXPORT_SYMBOL_IF_KUNIT(aa_inbounds);
strs->table = table;
strs->size = size; for (i = 0; i < size; i++) { char *str; int c, j, pos, size2 = aa_unpack_strdup(e, &str, NULL); /* aa_unpack_strdup verifies that the last character is *nullterminationbyte.
*/ if (!size2) goto fail;
table[i] = str; /* verify that name doesn't start with space */ if (isspace(*str)) goto fail;
/* count internal # of internal \0 */ for (c = j = 0; j < size2 - 1; j++) { if (!str[j]) {
pos = j;
c++;
}
} if (*str == ':') { /* first character after : must be valid */ if (!str[1]) goto fail; /* beginning with : requires an embedded \0, *verifythatexactly1internal\0exists *trailing\0alreadyverifiedbyaa_unpack_strdup * *convert\0backto:forlabel_parse
*/ if (c == 1)
str[pos] = ':'; elseif (c > 1) goto fail;
} elseif (c) /* fail - all other cases with embedded \0 */ goto fail;
} if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) goto fail; if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) goto fail;
} returntrue;
if (pdb->perms) { /* perms table present accept is index */
flags = TO_ACCEPT1_FLAG(YYTD_DATA32); if (aa_unpack_u32(e, &version, "permsv") && version > 2) /* accept2 used for dfa flags */
flags |= TO_ACCEPT2_FLAG(YYTD_DATA32);
} else { /* packed perms in accept1 and accept2 */
flags = TO_ACCEPT1_FLAG(YYTD_DATA32) |
TO_ACCEPT2_FLAG(YYTD_DATA32);
}
pdb->dfa = unpack_dfa(e, flags); if (IS_ERR(pdb->dfa)) {
error = PTR_ERR(pdb->dfa);
pdb->dfa = NULL;
*info = "failed to unpack - dfa"; goto fail;
} elseif (!pdb->dfa) { if (required_dfa) {
*info = "missing required dfa"; goto fail;
}
} else { /* *onlyunpackthefollowingifadfaispresent * *sadlystartwasgivendifferentnamesforfileandpolicydb *butsinceitisoptionalwecantryboth
*/ if (!aa_unpack_u32(e, &pdb->start[0], "start")) /* default start state */
pdb->start[0] = DFA_START; if (!aa_unpack_u32(e, &pdb->start[AA_CLASS_FILE], "dfa_start")) { /* default start state for xmatch and file dfa */
pdb->start[AA_CLASS_FILE] = DFA_START;
} /* setup class index */ for (i = AA_CLASS_FILE + 1; i <= AA_CLASS_LAST; i++) {
pdb->start[i] = aa_dfa_next(pdb->dfa, pdb->start[0],
i);
}
}
/* accept2 is in some cases being allocated, even with perms */ if (pdb->perms && !pdb->dfa->tables[YYTD_ID_ACCEPT2]) { /* add dfa flags table missing in v2 */
u32 noents = pdb->dfa->tables[YYTD_ID_ACCEPT]->td_lolen;
u16 tdflags = pdb->dfa->tables[YYTD_ID_ACCEPT]->td_flags;
size_t tsize = table_size(noents, tdflags);
/* check that we have the right struct being passed */ if (!aa_unpack_nameX(e, AA_STRUCT, "profile")) goto fail; if (!aa_unpack_str(e, &name, NULL)) goto fail; if (*name == '\0') goto fail;
tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len); if (tmpns) { if (!tmpname) {
info = "empty profile name"; goto fail;
}
*ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL); if (!*ns_name) {
info = "out of memory";
error = -ENOMEM; goto fail;
}
name = tmpname;
}
profile = aa_alloc_profile(name, NULL, GFP_KERNEL); if (!profile) {
info = "out of memory";
error = -ENOMEM; goto fail;
}
rules = profile->label.rules[0];
/* profile renaming is optional */
(void) aa_unpack_str(e, &profile->rename, "rename");
/* attachment string is optional */
(void) aa_unpack_str(e, &profile->attach.xmatch_str, "attach");
/* xmatch is optional and may be NULL */
error = unpack_pdb(e, &profile->attach.xmatch, false, false, &info); if (error) {
info = "bad xmatch"; goto fail;
}
/* neither xmatch_len not xmatch_perms are optional if xmatch is set */ if (profile->attach.xmatch->dfa) { if (!aa_unpack_u32(e, &tmp, NULL)) {
info = "missing xmatch len"; goto fail;
}
profile->attach.xmatch_len = tmp;
profile->attach.xmatch->start[AA_CLASS_XMATCH] = DFA_START; if (!profile->attach.xmatch->perms) {
error = aa_compat_map_xmatch(profile->attach.xmatch); if (error) {
info = "failed to convert xmatch permission table"; goto fail;
}
}
}
if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) goto fail;
/* path_flags is optional */ if (aa_unpack_u32(e, &profile->path_flags, "path_flags"))
profile->path_flags |= profile->label.flags &
PATH_MEDIATE_DELETED; else /* set a default value if path_flags field is not present */
profile->path_flags = PATH_MEDIATE_DELETED;
info = "failed to unpack profile capabilities"; if (!aa_unpack_cap_low(e, &rules->caps.allow, NULL)) goto fail; if (!aa_unpack_cap_low(e, &rules->caps.audit, NULL)) goto fail; if (!aa_unpack_cap_low(e, &rules->caps.quiet, NULL)) goto fail; if (!aa_unpack_cap_low(e, &tmpcap, NULL)) goto fail;
info = "failed to unpack upper profile capabilities"; if (aa_unpack_nameX(e, AA_STRUCT, "caps64")) { /* optional upper half of 64 bit caps */ if (!aa_unpack_cap_high(e, &rules->caps.allow, NULL)) goto fail; if (!aa_unpack_cap_high(e, &rules->caps.audit, NULL)) goto fail; if (!aa_unpack_cap_high(e, &rules->caps.quiet, NULL)) goto fail; if (!aa_unpack_cap_high(e, &tmpcap, NULL)) goto fail; if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) goto fail;
}
info = "failed to unpack extended profile capabilities"; if (aa_unpack_nameX(e, AA_STRUCT, "capsx")) { /* optional extended caps mediation mask */ if (!aa_unpack_cap_low(e, &rules->caps.extended, NULL)) goto fail; if (!aa_unpack_cap_high(e, &rules->caps.extended, NULL)) goto fail; if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) goto fail;
}
if (!unpack_xattrs(e, profile)) {
info = "failed to unpack profile xattrs"; goto fail;
}
if (!unpack_rlimits(e, rules)) {
info = "failed to unpack profile rlimits"; goto fail;
}
if (!unpack_secmark(e, rules)) {
info = "failed to unpack profile secmark rules"; goto fail;
}
if (aa_unpack_nameX(e, AA_STRUCT, "policydb")) { /* generic policy dfa - optional and may be NULL */
info = "failed to unpack policydb";
error = unpack_pdb(e, &rules->policy, true, false,
&info); if (error) goto fail; /* Fixup: drop when we get rid of start array */ if (aa_dfa_next(rules->policy->dfa, rules->policy->start[0],
AA_CLASS_FILE))
rules->policy->start[AA_CLASS_FILE] =
aa_dfa_next(rules->policy->dfa,
rules->policy->start[0],
AA_CLASS_FILE); if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) goto fail; if (!rules->policy->perms) {
error = aa_compat_map_policy(rules->policy,
e->version); if (error) {
info = "failed to remap policydb permission table"; goto fail;
}
}
} else {
rules->policy = aa_get_pdb(nullpdb);
} /* get file rules */
error = unpack_pdb(e, &rules->file, false, true, &info); if (error) { goto fail;
} elseif (rules->file->dfa) { if (!rules->file->perms) {
error = aa_compat_map_file(rules->file); if (error) {
info = "failed to remap file permission table"; goto fail;
}
}
} elseif (rules->policy->dfa &&
rules->policy->start[AA_CLASS_FILE]) {
aa_put_pdb(rules->file);
rules->file = aa_get_pdb(rules->policy);
} else {
aa_put_pdb(rules->file);
rules->file = aa_get_pdb(nullpdb);
}
error = -EPROTO; if (aa_unpack_nameX(e, AA_STRUCT, "data")) {
info = "out of memory";
profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); if (!profile->data) {
error = -ENOMEM; goto fail;
}
params.nelem_hint = 3;
params.key_len = sizeof(void *);
params.key_offset = offsetof(struct aa_data, key);
params.head_offset = offsetof(struct aa_data, head);
params.hashfn = strhash;
params.obj_cmpfn = datacmp;
if (rhashtable_init(profile->data, ¶ms)) {
info = "failed to init key, value hash table"; goto fail;
}
while (aa_unpack_strdup(e, &key, NULL)) {
data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) {
kfree_sensitive(key);
error = -ENOMEM; goto fail;
}
if (rhashtable_insert_fast(profile->data, &data->head,
profile->data->p)) {
kvfree_sensitive(data->data, data->size);
kfree_sensitive(data->key);
kfree_sensitive(data);
info = "failed to insert data to table"; goto fail;
}
}
if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) {
info = "failed to unpack end of key, value data table"; goto fail;
}
}
if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) {
info = "failed to unpack end of profile"; goto fail;
}
aa_compute_profile_mediates(profile);
return profile;
fail: if (error == 0) /* default error covers most cases */
error = -EPROTO; if (*ns_name) {
kfree(*ns_name);
*ns_name = NULL;
} if (profile)
name = NULL; elseif (!name)
name = "unknown";
audit_iface(profile, NULL, name, info, e, error);
aa_free_profile(profile);
/* get the interface version */ if (!aa_unpack_u32(e, &e->version, "version")) { if (required) {
audit_iface(NULL, NULL, NULL, "invalid profile format",
e, error); return error;
}
}
/* Check that the interface version is currently supported. *ifnotspecifiedusepreviousversion *Maskoffeverythingthatisnotkernelabiversion
*/ if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v9)) {
audit_iface(NULL, NULL, NULL, "unsupported interface version",
e, error); return error;
}
/* read the namespace if present */ if (aa_unpack_str(e, &name, "namespace")) { if (*name == '\0') {
audit_iface(NULL, NULL, NULL, "invalid namespace name",
e, error); return error;
} if (*ns && strcmp(*ns, name)) {
audit_iface(NULL, NULL, NULL, "invalid ns change", e,
error);
} elseif (!*ns) {
*ns = kstrdup(name, GFP_KERNEL); if (!*ns) return -ENOMEM;
}
}
return0;
}
/** *verify_dfa_accept_index-verifyacceptindexesareinrangeofpermstable *@dfa:thedfatocheckacceptindexesareinrange *@table_size:thepermissiontablesizetheindexesshouldbewithin
*/ staticbool verify_dfa_accept_index(struct aa_dfa *dfa, int table_size)
{ int i; for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) { if (ACCEPT_TABLE(dfa)[i] >= table_size) returnfalse;
} returntrue;
}
staticbool verify_perm(struct aa_perms *perm)
{ /* TODO: allow option to just force the perms into a valid state */ if (perm->allow & perm->deny) returnfalse; if (perm->subtree & ~perm->allow) returnfalse; if (perm->cond & (perm->allow | perm->deny)) returnfalse; if (perm->kill & perm->allow) returnfalse; if (perm->complain & (perm->allow | perm->deny)) returnfalse; if (perm->prompt & (perm->allow | perm->deny)) returnfalse; if (perm->complain & perm->prompt) returnfalse; if (perm->hide & perm->allow) returnfalse;
returntrue;
}
staticbool verify_perms(struct aa_policydb *pdb)
{ int i; int xidx, xmax = -1;
for (i = 0; i < pdb->size; i++) { if (!verify_perm(&pdb->perms[i])) returnfalse; /* verify indexes into str table */ if ((pdb->perms[i].xindex & AA_X_TYPE_MASK) == AA_X_TABLE) {
xidx = pdb->perms[i].xindex & AA_X_INDEX_MASK; if (xidx >= pdb->trans.size) returnfalse; if (xmax < xidx)
xmax = xidx;
} if (pdb->perms[i].tag && pdb->perms[i].tag >= pdb->trans.size) returnfalse; if (pdb->perms[i].label &&
pdb->perms[i].label >= pdb->trans.size) returnfalse;
} /* deal with incorrectly constructed string tables */ if (xmax == -1) {
aa_free_str_table(&pdb->trans);
} elseif (pdb->trans.size > xmax + 1) { if (!aa_resize_str_table(&pdb->trans, xmax + 1, GFP_KERNEL)) returnfalse;
} returntrue;
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.20Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.