Skip to content

Commit

Permalink
apparmor: change aad apparmor_audit_data macro to a fn macro
Browse files Browse the repository at this point in the history
The aad macro can replace aad strings when it is not intended to. Switch
to a fn macro so it is only applied when intended.

Also at the same time cleanup audit_data initialization by putting
common boiler plate behind a macro, and dropping the gfp_t parameter
which will become useless.

Signed-off-by: John Johansen <[email protected]>
  • Loading branch information
John Johansen committed Jan 16, 2017
1 parent 47f6e5c commit ef88a7a
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 161 deletions.
42 changes: 20 additions & 22 deletions security/apparmor/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,23 @@ static void audit_pre(struct audit_buffer *ab, void *ca)

if (aa_g_audit_header) {
audit_log_format(ab, "apparmor=");
audit_log_string(ab, aa_audit_type[sa->aad->type]);
audit_log_string(ab, aa_audit_type[aad(sa)->type]);
}

if (sa->aad->op) {
if (aad(sa)->op) {
audit_log_format(ab, " operation=");
audit_log_string(ab, sa->aad->op);
audit_log_string(ab, aad(sa)->op);
}

if (sa->aad->info) {
if (aad(sa)->info) {
audit_log_format(ab, " info=");
audit_log_string(ab, sa->aad->info);
if (sa->aad->error)
audit_log_format(ab, " error=%d", sa->aad->error);
audit_log_string(ab, aad(sa)->info);
if (aad(sa)->error)
audit_log_format(ab, " error=%d", aad(sa)->error);
}

if (sa->aad->profile) {
struct aa_profile *profile = sa->aad->profile;
if (aad(sa)->profile) {
struct aa_profile *profile = aad(sa)->profile;
if (profile->ns != root_ns) {
audit_log_format(ab, " namespace=");
audit_log_untrustedstring(ab, profile->ns->base.hname);
Expand All @@ -87,9 +87,9 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
audit_log_untrustedstring(ab, profile->base.hname);
}

if (sa->aad->name) {
if (aad(sa)->name) {
audit_log_format(ab, " name=");
audit_log_untrustedstring(ab, sa->aad->name);
audit_log_untrustedstring(ab, aad(sa)->name);
}
}

Expand All @@ -101,30 +101,28 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
void aa_audit_msg(int type, struct common_audit_data *sa,
void (*cb) (struct audit_buffer *, void *))
{
sa->aad->type = type;
aad(sa)->type = type;
common_lsm_audit(sa, audit_pre, cb);
}

/**
* aa_audit - Log a profile based audit event to the audit subsystem
* @type: audit type for the message
* @profile: profile to check against (NOT NULL)
* @gfp: allocation flags to use
* @sa: audit event (NOT NULL)
* @cb: optional callback fn for type specific fields (MAYBE NULL)
*
* Handle default message switching based off of audit mode flags
*
* Returns: error on failure
*/
int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
struct common_audit_data *sa,
int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
void (*cb) (struct audit_buffer *, void *))
{
BUG_ON(!profile);

if (type == AUDIT_APPARMOR_AUTO) {
if (likely(!sa->aad->error)) {
if (likely(!aad(sa)->error)) {
if (AUDIT_MODE(profile) != AUDIT_ALL)
return 0;
type = AUDIT_APPARMOR_AUDIT;
Expand All @@ -136,23 +134,23 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
if (AUDIT_MODE(profile) == AUDIT_QUIET ||
(type == AUDIT_APPARMOR_DENIED &&
AUDIT_MODE(profile) == AUDIT_QUIET))
return sa->aad->error;
return aad(sa)->error;

if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
type = AUDIT_APPARMOR_KILL;

if (!unconfined(profile))
sa->aad->profile = profile;
aad(sa)->profile = profile;

aa_audit_msg(type, sa, cb);

if (sa->aad->type == AUDIT_APPARMOR_KILL)
if (aad(sa)->type == AUDIT_APPARMOR_KILL)
(void)send_sig_info(SIGKILL, NULL,
sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
sa->u.tsk : current);

if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
return complain_error(sa->aad->error);
if (aad(sa)->type == AUDIT_APPARMOR_ALLOWED)
return complain_error(aad(sa)->error);

return sa->aad->error;
return aad(sa)->error;
}
10 changes: 3 additions & 7 deletions security/apparmor/capability.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,9 @@ static int audit_caps(struct aa_profile *profile, int cap, int error)
{
struct audit_cache *ent;
int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
sa.type = LSM_AUDIT_DATA_CAP;
sa.aad = &aad;
DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
sa.u.cap = cap;
sa.aad->op = OP_CAPABLE;
sa.aad->error = error;
aad(&sa)->error = error;

if (likely(!error)) {
/* test if auditing is being forced */
Expand Down Expand Up @@ -104,7 +100,7 @@ static int audit_caps(struct aa_profile *profile, int cap, int error)
}
put_cpu_var(audit_cache);

return aa_audit(type, profile, GFP_ATOMIC, &sa, audit_cb);
return aa_audit(type, profile, &sa, audit_cb);
}

/**
Expand Down
13 changes: 6 additions & 7 deletions security/apparmor/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
aa_clear_task_ctx_trans(ctx);

audit:
error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
name,
error = aa_audit_file(profile, &perms, OP_EXEC, MAY_EXEC, name,
new_profile ? new_profile->base.hname : NULL,
cond.uid, info, error);

Expand Down Expand Up @@ -714,9 +713,9 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)

audit:
if (!permtest)
error = aa_audit_file(profile, &perms, GFP_KERNEL,
OP_CHANGE_HAT, AA_MAY_CHANGEHAT, NULL,
target, GLOBAL_ROOT_UID, info, error);
error = aa_audit_file(profile, &perms, OP_CHANGE_HAT,
AA_MAY_CHANGEHAT, NULL, target,
GLOBAL_ROOT_UID, info, error);

out:
aa_put_profile(hat);
Expand Down Expand Up @@ -842,8 +841,8 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,

audit:
if (!permtest)
error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request,
name, hname, GLOBAL_ROOT_UID, info, error);
error = aa_audit_file(profile, &perms, op, request, name,
hname, GLOBAL_ROOT_UID, info, error);

aa_put_ns(ns);
aa_put_profile(target);
Expand Down
69 changes: 34 additions & 35 deletions security/apparmor/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,24 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
struct common_audit_data *sa = va;
kuid_t fsuid = current_fsuid();

if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
if (aad(sa)->fs.request & AA_AUDIT_FILE_MASK) {
audit_log_format(ab, " requested_mask=");
audit_file_mask(ab, sa->aad->fs.request);
audit_file_mask(ab, aad(sa)->fs.request);
}
if (sa->aad->fs.denied & AA_AUDIT_FILE_MASK) {
if (aad(sa)->fs.denied & AA_AUDIT_FILE_MASK) {
audit_log_format(ab, " denied_mask=");
audit_file_mask(ab, sa->aad->fs.denied);
audit_file_mask(ab, aad(sa)->fs.denied);
}
if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
if (aad(sa)->fs.request & AA_AUDIT_FILE_MASK) {
audit_log_format(ab, " fsuid=%d",
from_kuid(&init_user_ns, fsuid));
audit_log_format(ab, " ouid=%d",
from_kuid(&init_user_ns, sa->aad->fs.ouid));
from_kuid(&init_user_ns, aad(sa)->fs.ouid));
}

if (sa->aad->fs.target) {
if (aad(sa)->fs.target) {
audit_log_format(ab, " target=");
audit_log_untrustedstring(ab, sa->aad->fs.target);
audit_log_untrustedstring(ab, aad(sa)->fs.target);
}
}

Expand All @@ -104,54 +104,53 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
* Returns: %0 or error on failure
*/
int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
gfp_t gfp, const char *op, u32 request, const char *name,
const char *op, u32 request, const char *name,
const char *target, kuid_t ouid, const char *info, int error)
{
int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
sa.type = LSM_AUDIT_DATA_TASK;
DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op);

sa.u.tsk = NULL;
aad(&sa)->fs.request = request;
aad(&sa)->name = name;
aad(&sa)->fs.target = target;
aad(&sa)->fs.ouid = ouid;
aad(&sa)->info = info;
aad(&sa)->error = error;
sa.u.tsk = NULL;
sa.aad = &aad;
aad.op = op,
aad.fs.request = request;
aad.name = name;
aad.fs.target = target;
aad.fs.ouid = ouid;
aad.info = info;
aad.error = error;

if (likely(!sa.aad->error)) {

if (likely(!aad(&sa)->error)) {
u32 mask = perms->audit;

if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
mask = 0xffff;

/* mask off perms that are not being force audited */
sa.aad->fs.request &= mask;
aad(&sa)->fs.request &= mask;

if (likely(!sa.aad->fs.request))
if (likely(!aad(&sa)->fs.request))
return 0;
type = AUDIT_APPARMOR_AUDIT;
} else {
/* only report permissions that were denied */
sa.aad->fs.request = sa.aad->fs.request & ~perms->allow;
aad(&sa)->fs.request = aad(&sa)->fs.request & ~perms->allow;
AA_BUG(!aad(&sa)->fs.request);

if (sa.aad->fs.request & perms->kill)
if (aad(&sa)->fs.request & perms->kill)
type = AUDIT_APPARMOR_KILL;

/* quiet known rejects, assumes quiet and kill do not overlap */
if ((sa.aad->fs.request & perms->quiet) &&
if ((aad(&sa)->fs.request & perms->quiet) &&
AUDIT_MODE(profile) != AUDIT_NOQUIET &&
AUDIT_MODE(profile) != AUDIT_ALL)
sa.aad->fs.request &= ~perms->quiet;
aad(&sa)->fs.request &= ~perms->quiet;

if (!sa.aad->fs.request)
return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
if (!aad(&sa)->fs.request)
return COMPLAIN_MODE(profile) ? 0 : aad(&sa)->error;
}

sa.aad->fs.denied = sa.aad->fs.request & ~perms->allow;
return aa_audit(type, profile, gfp, &sa, file_audit_cb);
aad(&sa)->fs.denied = aad(&sa)->fs.request & ~perms->allow;
return aa_audit(type, profile, &sa, file_audit_cb);
}

/**
Expand Down Expand Up @@ -302,8 +301,8 @@ int aa_path_perm(const char *op, struct aa_profile *profile,
if (request & ~perms.allow)
error = -EACCES;
}
error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request, name,
NULL, cond->uid, info, error);
error = aa_audit_file(profile, &perms, op, request, name, NULL,
cond->uid, info, error);
kfree(buffer);

return error;
Expand Down Expand Up @@ -430,7 +429,7 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
error = 0;

audit:
error = aa_audit_file(profile, &lperms, GFP_KERNEL, OP_LINK, request,
error = aa_audit_file(profile, &lperms, OP_LINK, request,
lname, tname, cond.uid, info, error);
kfree(buffer);
kfree(buffer2);
Expand Down
43 changes: 31 additions & 12 deletions security/apparmor/include/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,34 +108,53 @@ struct apparmor_audit_data {
const char *name;
const char *info;
union {
void *target;
/* these entries require a custom callback fn */
struct {
struct aa_profile *peer;
struct {
const char *target;
u32 request;
u32 denied;
kuid_t ouid;
} fs;
};
struct {
const char *name;
long pos;
const char *ns;
void *target;
} iface;
struct {
int rlim;
unsigned long max;
} rlim;
struct {
const char *target;
u32 request;
u32 denied;
kuid_t ouid;
} fs;
};
};

/* define a short hand for apparmor_audit_data structure */
#define aad apparmor_audit_data
/* macros for dealing with apparmor_audit_data structure */
#define aad(SA) ((SA)->apparmor_audit_data)
#define DEFINE_AUDIT_DATA(NAME, T, X) \
/* TODO: cleanup audit init so we don't need _aad = {0,} */ \
struct apparmor_audit_data NAME ## _aad = { .op = (X), }; \
struct common_audit_data NAME = \
{ \
.type = (T), \
.u.tsk = NULL, \
}; \
NAME.apparmor_audit_data = &(NAME ## _aad)

void aa_audit_msg(int type, struct common_audit_data *sa,
void (*cb) (struct audit_buffer *, void *));
int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
struct common_audit_data *sa,
int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
void (*cb) (struct audit_buffer *, void *));

#define aa_audit_error(ERROR, SA, CB) \
({ \
aad((SA))->error = (ERROR); \
aa_audit_msg(AUDIT_APPARMOR_ERROR, (SA), (CB)); \
aad((SA))->error; \
})


static inline int complain_error(int error)
{
if (error == -EPERM || error == -EACCES)
Expand Down
2 changes: 1 addition & 1 deletion security/apparmor/include/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ static inline u16 dfa_map_xindex(u16 mask)
dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff)

int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
gfp_t gfp, const char *op, u32 request, const char *name,
const char *op, u32 request, const char *name,
const char *target, kuid_t ouid, const char *info, int error);

/**
Expand Down
Loading

0 comments on commit ef88a7a

Please sign in to comment.