Loading security/apparmor/file.c +15 −15 Original line number Diff line number Diff line Loading @@ -56,15 +56,15 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) struct common_audit_data *sa = va; kuid_t fsuid = current_fsuid(); if (aad(sa)->fs.request & AA_AUDIT_FILE_MASK) { if (aad(sa)->request & AA_AUDIT_FILE_MASK) { audit_log_format(ab, " requested_mask="); audit_file_mask(ab, aad(sa)->fs.request); audit_file_mask(ab, aad(sa)->request); } if (aad(sa)->fs.denied & AA_AUDIT_FILE_MASK) { if (aad(sa)->denied & AA_AUDIT_FILE_MASK) { audit_log_format(ab, " denied_mask="); audit_file_mask(ab, aad(sa)->fs.denied); audit_file_mask(ab, aad(sa)->denied); } if (aad(sa)->fs.request & AA_AUDIT_FILE_MASK) { if (aad(sa)->request & AA_AUDIT_FILE_MASK) { audit_log_format(ab, " fsuid=%d", from_kuid(&init_user_ns, fsuid)); audit_log_format(ab, " ouid=%d", Loading Loading @@ -100,7 +100,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op); sa.u.tsk = NULL; aad(&sa)->fs.request = request; aad(&sa)->request = request; aad(&sa)->name = name; aad(&sa)->fs.target = target; aad(&sa)->fs.ouid = ouid; Loading @@ -115,30 +115,30 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, mask = 0xffff; /* mask off perms that are not being force audited */ aad(&sa)->fs.request &= mask; aad(&sa)->request &= mask; if (likely(!aad(&sa)->fs.request)) if (likely(!aad(&sa)->request)) return 0; type = AUDIT_APPARMOR_AUDIT; } else { /* only report permissions that were denied */ aad(&sa)->fs.request = aad(&sa)->fs.request & ~perms->allow; AA_BUG(!aad(&sa)->fs.request); aad(&sa)->request = aad(&sa)->request & ~perms->allow; AA_BUG(!aad(&sa)->request); if (aad(&sa)->fs.request & perms->kill) if (aad(&sa)->request & perms->kill) type = AUDIT_APPARMOR_KILL; /* quiet known rejects, assumes quiet and kill do not overlap */ if ((aad(&sa)->fs.request & perms->quiet) && if ((aad(&sa)->request & perms->quiet) && AUDIT_MODE(profile) != AUDIT_NOQUIET && AUDIT_MODE(profile) != AUDIT_ALL) aad(&sa)->fs.request &= ~perms->quiet; aad(&sa)->request &= ~perms->quiet; if (!aad(&sa)->fs.request) if (!aad(&sa)->request) return COMPLAIN_MODE(profile) ? 0 : aad(&sa)->error; } aad(&sa)->fs.denied = aad(&sa)->fs.request & ~perms->allow; aad(&sa)->denied = aad(&sa)->request & ~perms->allow; return aa_audit(type, profile, &sa, file_audit_cb); } Loading security/apparmor/include/audit.h +2 −2 Original line number Diff line number Diff line Loading @@ -107,14 +107,14 @@ struct apparmor_audit_data { void *profile; const char *name; const char *info; u32 request; u32 denied; union { /* these entries require a custom callback fn */ struct { struct aa_profile *peer; struct { const char *target; u32 request; u32 denied; kuid_t ouid; } fs; }; Loading security/apparmor/include/perms.h +34 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,40 @@ extern const char aa_file_perm_chrs[]; extern const char *aa_file_perm_names[]; struct aa_perms { u32 allow; u32 audit; /* set only when allow is set */ u32 deny; /* explicit deny, or conflict if allow also set */ u32 quiet; /* set only when ~allow | deny */ u32 kill; /* set only when ~allow | deny */ u32 stop; /* set only when ~allow | deny */ u32 complain; /* accumulates only used when ~allow & ~deny */ u32 cond; /* set only when ~allow and ~deny */ u32 hide; /* set only when ~allow | deny */ u32 prompt; /* accumulates only used when ~allow & ~deny */ /* Reserved: * u32 subtree; / * set only when allow is set * / */ u16 xindex; }; #define ALL_PERMS_MASK 0xffffffff extern struct aa_perms allperms; struct aa_profile; void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask); void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, u32 chrsmask, const char **names, u32 namesmask); void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms); void aa_compute_perms(struct aa_dfa *dfa, unsigned int state, struct aa_perms *perms); #endif /* __AA_PERM_H */ security/apparmor/lib.c +102 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ #include "include/perms.h" #include "include/policy.h" struct aa_perms allperms = { .allow = ALL_PERMS_MASK, .quiet = ALL_PERMS_MASK, .hide = ALL_PERMS_MASK }; /** * aa_split_fqname - split a fqname into a profile and namespace name * @fqname: a full qualified name in namespace profile format (NOT NULL) Loading Loading @@ -188,6 +192,104 @@ void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask) *str = '\0'; } void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask) { const char *fmt = "%s"; unsigned int i, perm = 1; bool prev = false; for (i = 0; i < 32; perm <<= 1, i++) { if (mask & perm) { audit_log_format(ab, fmt, names[i]); if (!prev) { prev = true; fmt = " %s"; } } } } void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, u32 chrsmask, const char **names, u32 namesmask) { char str[33]; audit_log_format(ab, "\""); if ((mask & chrsmask) && chrs) { aa_perm_mask_to_str(str, chrs, mask & chrsmask); mask &= ~chrsmask; audit_log_format(ab, "%s", str); if (mask & namesmask) audit_log_format(ab, " "); } if ((mask & namesmask) && names) aa_audit_perm_names(ab, names, mask & namesmask); audit_log_format(ab, "\""); } /** * aa_apply_modes_to_perms - apply namespace and profile flags to perms * @profile: that perms where computed from * @perms: perms to apply mode modifiers to * * TODO: split into profile and ns based flags for when accumulating perms */ void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms) { switch (AUDIT_MODE(profile)) { case AUDIT_ALL: perms->audit = ALL_PERMS_MASK; /* fall through */ case AUDIT_NOQUIET: perms->quiet = 0; break; case AUDIT_QUIET: perms->audit = 0; /* fall through */ case AUDIT_QUIET_DENIED: perms->quiet = ALL_PERMS_MASK; break; } if (KILL_MODE(profile)) perms->kill = ALL_PERMS_MASK; else if (COMPLAIN_MODE(profile)) perms->complain = ALL_PERMS_MASK; /* * TODO: * else if (PROMPT_MODE(profile)) * perms->prompt = ALL_PERMS_MASK; */ } static u32 map_other(u32 x) { return ((x & 0x3) << 8) | /* SETATTR/GETATTR */ ((x & 0x1c) << 18) | /* ACCEPT/BIND/LISTEN */ ((x & 0x60) << 19); /* SETOPT/GETOPT */ } void aa_compute_perms(struct aa_dfa *dfa, unsigned int state, struct aa_perms *perms) { perms->deny = 0; perms->kill = perms->stop = 0; perms->complain = perms->cond = 0; perms->hide = 0; perms->prompt = 0; perms->allow = dfa_user_allow(dfa, state); perms->audit = dfa_user_audit(dfa, state); perms->quiet = dfa_user_quiet(dfa, state); /* for v5 perm mapping in the policydb, the other set is used * to extend the general perm set */ perms->allow |= map_other(dfa_other_allow(dfa, state)); perms->audit |= map_other(dfa_other_audit(dfa, state)); perms->quiet |= map_other(dfa_other_quiet(dfa, state)); // perms->xindex = dfa_user_xindex(dfa, state); } /** * aa_policy_init - initialize a policy structure * @policy: policy to initialize (NOT NULL) Loading Loading
security/apparmor/file.c +15 −15 Original line number Diff line number Diff line Loading @@ -56,15 +56,15 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) struct common_audit_data *sa = va; kuid_t fsuid = current_fsuid(); if (aad(sa)->fs.request & AA_AUDIT_FILE_MASK) { if (aad(sa)->request & AA_AUDIT_FILE_MASK) { audit_log_format(ab, " requested_mask="); audit_file_mask(ab, aad(sa)->fs.request); audit_file_mask(ab, aad(sa)->request); } if (aad(sa)->fs.denied & AA_AUDIT_FILE_MASK) { if (aad(sa)->denied & AA_AUDIT_FILE_MASK) { audit_log_format(ab, " denied_mask="); audit_file_mask(ab, aad(sa)->fs.denied); audit_file_mask(ab, aad(sa)->denied); } if (aad(sa)->fs.request & AA_AUDIT_FILE_MASK) { if (aad(sa)->request & AA_AUDIT_FILE_MASK) { audit_log_format(ab, " fsuid=%d", from_kuid(&init_user_ns, fsuid)); audit_log_format(ab, " ouid=%d", Loading Loading @@ -100,7 +100,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op); sa.u.tsk = NULL; aad(&sa)->fs.request = request; aad(&sa)->request = request; aad(&sa)->name = name; aad(&sa)->fs.target = target; aad(&sa)->fs.ouid = ouid; Loading @@ -115,30 +115,30 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, mask = 0xffff; /* mask off perms that are not being force audited */ aad(&sa)->fs.request &= mask; aad(&sa)->request &= mask; if (likely(!aad(&sa)->fs.request)) if (likely(!aad(&sa)->request)) return 0; type = AUDIT_APPARMOR_AUDIT; } else { /* only report permissions that were denied */ aad(&sa)->fs.request = aad(&sa)->fs.request & ~perms->allow; AA_BUG(!aad(&sa)->fs.request); aad(&sa)->request = aad(&sa)->request & ~perms->allow; AA_BUG(!aad(&sa)->request); if (aad(&sa)->fs.request & perms->kill) if (aad(&sa)->request & perms->kill) type = AUDIT_APPARMOR_KILL; /* quiet known rejects, assumes quiet and kill do not overlap */ if ((aad(&sa)->fs.request & perms->quiet) && if ((aad(&sa)->request & perms->quiet) && AUDIT_MODE(profile) != AUDIT_NOQUIET && AUDIT_MODE(profile) != AUDIT_ALL) aad(&sa)->fs.request &= ~perms->quiet; aad(&sa)->request &= ~perms->quiet; if (!aad(&sa)->fs.request) if (!aad(&sa)->request) return COMPLAIN_MODE(profile) ? 0 : aad(&sa)->error; } aad(&sa)->fs.denied = aad(&sa)->fs.request & ~perms->allow; aad(&sa)->denied = aad(&sa)->request & ~perms->allow; return aa_audit(type, profile, &sa, file_audit_cb); } Loading
security/apparmor/include/audit.h +2 −2 Original line number Diff line number Diff line Loading @@ -107,14 +107,14 @@ struct apparmor_audit_data { void *profile; const char *name; const char *info; u32 request; u32 denied; union { /* these entries require a custom callback fn */ struct { struct aa_profile *peer; struct { const char *target; u32 request; u32 denied; kuid_t ouid; } fs; }; Loading
security/apparmor/include/perms.h +34 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,40 @@ extern const char aa_file_perm_chrs[]; extern const char *aa_file_perm_names[]; struct aa_perms { u32 allow; u32 audit; /* set only when allow is set */ u32 deny; /* explicit deny, or conflict if allow also set */ u32 quiet; /* set only when ~allow | deny */ u32 kill; /* set only when ~allow | deny */ u32 stop; /* set only when ~allow | deny */ u32 complain; /* accumulates only used when ~allow & ~deny */ u32 cond; /* set only when ~allow and ~deny */ u32 hide; /* set only when ~allow | deny */ u32 prompt; /* accumulates only used when ~allow & ~deny */ /* Reserved: * u32 subtree; / * set only when allow is set * / */ u16 xindex; }; #define ALL_PERMS_MASK 0xffffffff extern struct aa_perms allperms; struct aa_profile; void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask); void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, u32 chrsmask, const char **names, u32 namesmask); void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms); void aa_compute_perms(struct aa_dfa *dfa, unsigned int state, struct aa_perms *perms); #endif /* __AA_PERM_H */
security/apparmor/lib.c +102 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ #include "include/perms.h" #include "include/policy.h" struct aa_perms allperms = { .allow = ALL_PERMS_MASK, .quiet = ALL_PERMS_MASK, .hide = ALL_PERMS_MASK }; /** * aa_split_fqname - split a fqname into a profile and namespace name * @fqname: a full qualified name in namespace profile format (NOT NULL) Loading Loading @@ -188,6 +192,104 @@ void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask) *str = '\0'; } void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask) { const char *fmt = "%s"; unsigned int i, perm = 1; bool prev = false; for (i = 0; i < 32; perm <<= 1, i++) { if (mask & perm) { audit_log_format(ab, fmt, names[i]); if (!prev) { prev = true; fmt = " %s"; } } } } void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, u32 chrsmask, const char **names, u32 namesmask) { char str[33]; audit_log_format(ab, "\""); if ((mask & chrsmask) && chrs) { aa_perm_mask_to_str(str, chrs, mask & chrsmask); mask &= ~chrsmask; audit_log_format(ab, "%s", str); if (mask & namesmask) audit_log_format(ab, " "); } if ((mask & namesmask) && names) aa_audit_perm_names(ab, names, mask & namesmask); audit_log_format(ab, "\""); } /** * aa_apply_modes_to_perms - apply namespace and profile flags to perms * @profile: that perms where computed from * @perms: perms to apply mode modifiers to * * TODO: split into profile and ns based flags for when accumulating perms */ void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms) { switch (AUDIT_MODE(profile)) { case AUDIT_ALL: perms->audit = ALL_PERMS_MASK; /* fall through */ case AUDIT_NOQUIET: perms->quiet = 0; break; case AUDIT_QUIET: perms->audit = 0; /* fall through */ case AUDIT_QUIET_DENIED: perms->quiet = ALL_PERMS_MASK; break; } if (KILL_MODE(profile)) perms->kill = ALL_PERMS_MASK; else if (COMPLAIN_MODE(profile)) perms->complain = ALL_PERMS_MASK; /* * TODO: * else if (PROMPT_MODE(profile)) * perms->prompt = ALL_PERMS_MASK; */ } static u32 map_other(u32 x) { return ((x & 0x3) << 8) | /* SETATTR/GETATTR */ ((x & 0x1c) << 18) | /* ACCEPT/BIND/LISTEN */ ((x & 0x60) << 19); /* SETOPT/GETOPT */ } void aa_compute_perms(struct aa_dfa *dfa, unsigned int state, struct aa_perms *perms) { perms->deny = 0; perms->kill = perms->stop = 0; perms->complain = perms->cond = 0; perms->hide = 0; perms->prompt = 0; perms->allow = dfa_user_allow(dfa, state); perms->audit = dfa_user_audit(dfa, state); perms->quiet = dfa_user_quiet(dfa, state); /* for v5 perm mapping in the policydb, the other set is used * to extend the general perm set */ perms->allow |= map_other(dfa_other_allow(dfa, state)); perms->audit |= map_other(dfa_other_audit(dfa, state)); perms->quiet |= map_other(dfa_other_quiet(dfa, state)); // perms->xindex = dfa_user_xindex(dfa, state); } /** * aa_policy_init - initialize a policy structure * @policy: policy to initialize (NOT NULL) Loading