Commit ef88a7ac authored by John Johansen's avatar John Johansen

apparmor: change aad apparmor_audit_data macro to a fn macro

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: default avatarJohn Johansen <john.johansen@canonical.com>
parent 47f6e5cc
...@@ -62,23 +62,23 @@ static void audit_pre(struct audit_buffer *ab, void *ca) ...@@ -62,23 +62,23 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
if (aa_g_audit_header) { if (aa_g_audit_header) {
audit_log_format(ab, "apparmor="); 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_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_format(ab, " info=");
audit_log_string(ab, sa->aad->info); audit_log_string(ab, aad(sa)->info);
if (sa->aad->error) if (aad(sa)->error)
audit_log_format(ab, " error=%d", sa->aad->error); audit_log_format(ab, " error=%d", aad(sa)->error);
} }
if (sa->aad->profile) { if (aad(sa)->profile) {
struct aa_profile *profile = sa->aad->profile; struct aa_profile *profile = aad(sa)->profile;
if (profile->ns != root_ns) { if (profile->ns != root_ns) {
audit_log_format(ab, " namespace="); audit_log_format(ab, " namespace=");
audit_log_untrustedstring(ab, profile->ns->base.hname); audit_log_untrustedstring(ab, profile->ns->base.hname);
...@@ -87,9 +87,9 @@ static void audit_pre(struct audit_buffer *ab, void *ca) ...@@ -87,9 +87,9 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
audit_log_untrustedstring(ab, profile->base.hname); audit_log_untrustedstring(ab, profile->base.hname);
} }
if (sa->aad->name) { if (aad(sa)->name) {
audit_log_format(ab, " name="); audit_log_format(ab, " name=");
audit_log_untrustedstring(ab, sa->aad->name); audit_log_untrustedstring(ab, aad(sa)->name);
} }
} }
...@@ -101,7 +101,7 @@ static void audit_pre(struct audit_buffer *ab, void *ca) ...@@ -101,7 +101,7 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
void aa_audit_msg(int type, struct common_audit_data *sa, void aa_audit_msg(int type, struct common_audit_data *sa,
void (*cb) (struct audit_buffer *, void *)) void (*cb) (struct audit_buffer *, void *))
{ {
sa->aad->type = type; aad(sa)->type = type;
common_lsm_audit(sa, audit_pre, cb); common_lsm_audit(sa, audit_pre, cb);
} }
...@@ -109,7 +109,6 @@ void aa_audit_msg(int type, struct common_audit_data *sa, ...@@ -109,7 +109,6 @@ void aa_audit_msg(int type, struct common_audit_data *sa,
* aa_audit - Log a profile based audit event to the audit subsystem * aa_audit - Log a profile based audit event to the audit subsystem
* @type: audit type for the message * @type: audit type for the message
* @profile: profile to check against (NOT NULL) * @profile: profile to check against (NOT NULL)
* @gfp: allocation flags to use
* @sa: audit event (NOT NULL) * @sa: audit event (NOT NULL)
* @cb: optional callback fn for type specific fields (MAYBE NULL) * @cb: optional callback fn for type specific fields (MAYBE NULL)
* *
...@@ -117,14 +116,13 @@ void aa_audit_msg(int type, struct common_audit_data *sa, ...@@ -117,14 +116,13 @@ void aa_audit_msg(int type, struct common_audit_data *sa,
* *
* Returns: error on failure * Returns: error on failure
*/ */
int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
struct common_audit_data *sa,
void (*cb) (struct audit_buffer *, void *)) void (*cb) (struct audit_buffer *, void *))
{ {
BUG_ON(!profile); BUG_ON(!profile);
if (type == AUDIT_APPARMOR_AUTO) { if (type == AUDIT_APPARMOR_AUTO) {
if (likely(!sa->aad->error)) { if (likely(!aad(sa)->error)) {
if (AUDIT_MODE(profile) != AUDIT_ALL) if (AUDIT_MODE(profile) != AUDIT_ALL)
return 0; return 0;
type = AUDIT_APPARMOR_AUDIT; type = AUDIT_APPARMOR_AUDIT;
...@@ -136,23 +134,23 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, ...@@ -136,23 +134,23 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
if (AUDIT_MODE(profile) == AUDIT_QUIET || if (AUDIT_MODE(profile) == AUDIT_QUIET ||
(type == AUDIT_APPARMOR_DENIED && (type == AUDIT_APPARMOR_DENIED &&
AUDIT_MODE(profile) == AUDIT_QUIET)) AUDIT_MODE(profile) == AUDIT_QUIET))
return sa->aad->error; return aad(sa)->error;
if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED) if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
type = AUDIT_APPARMOR_KILL; type = AUDIT_APPARMOR_KILL;
if (!unconfined(profile)) if (!unconfined(profile))
sa->aad->profile = profile; aad(sa)->profile = profile;
aa_audit_msg(type, sa, cb); 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, (void)send_sig_info(SIGKILL, NULL,
sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ? sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
sa->u.tsk : current); sa->u.tsk : current);
if (sa->aad->type == AUDIT_APPARMOR_ALLOWED) if (aad(sa)->type == AUDIT_APPARMOR_ALLOWED)
return complain_error(sa->aad->error); return complain_error(aad(sa)->error);
return sa->aad->error; return aad(sa)->error;
} }
...@@ -66,13 +66,9 @@ static int audit_caps(struct aa_profile *profile, int cap, int error) ...@@ -66,13 +66,9 @@ static int audit_caps(struct aa_profile *profile, int cap, int error)
{ {
struct audit_cache *ent; struct audit_cache *ent;
int type = AUDIT_APPARMOR_AUTO; int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa; DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
struct apparmor_audit_data aad = {0,};
sa.type = LSM_AUDIT_DATA_CAP;
sa.aad = &aad;
sa.u.cap = cap; sa.u.cap = cap;
sa.aad->op = OP_CAPABLE; aad(&sa)->error = error;
sa.aad->error = error;
if (likely(!error)) { if (likely(!error)) {
/* test if auditing is being forced */ /* test if auditing is being forced */
...@@ -104,7 +100,7 @@ static int audit_caps(struct aa_profile *profile, int cap, int error) ...@@ -104,7 +100,7 @@ static int audit_caps(struct aa_profile *profile, int cap, int error)
} }
put_cpu_var(audit_cache); put_cpu_var(audit_cache);
return aa_audit(type, profile, GFP_ATOMIC, &sa, audit_cb); return aa_audit(type, profile, &sa, audit_cb);
} }
/** /**
......
...@@ -508,8 +508,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) ...@@ -508,8 +508,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
aa_clear_task_ctx_trans(ctx); aa_clear_task_ctx_trans(ctx);
audit: audit:
error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC, error = aa_audit_file(profile, &perms, OP_EXEC, MAY_EXEC, name,
name,
new_profile ? new_profile->base.hname : NULL, new_profile ? new_profile->base.hname : NULL,
cond.uid, info, error); cond.uid, info, error);
...@@ -714,9 +713,9 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) ...@@ -714,9 +713,9 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
audit: audit:
if (!permtest) if (!permtest)
error = aa_audit_file(profile, &perms, GFP_KERNEL, error = aa_audit_file(profile, &perms, OP_CHANGE_HAT,
OP_CHANGE_HAT, AA_MAY_CHANGEHAT, NULL, AA_MAY_CHANGEHAT, NULL, target,
target, GLOBAL_ROOT_UID, info, error); GLOBAL_ROOT_UID, info, error);
out: out:
aa_put_profile(hat); aa_put_profile(hat);
...@@ -842,8 +841,8 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, ...@@ -842,8 +841,8 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
audit: audit:
if (!permtest) if (!permtest)
error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request, error = aa_audit_file(profile, &perms, op, request, name,
name, hname, GLOBAL_ROOT_UID, info, error); hname, GLOBAL_ROOT_UID, info, error);
aa_put_ns(ns); aa_put_ns(ns);
aa_put_profile(target); aa_put_profile(target);
......
...@@ -67,24 +67,24 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) ...@@ -67,24 +67,24 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
struct common_audit_data *sa = va; struct common_audit_data *sa = va;
kuid_t fsuid = current_fsuid(); 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_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_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", audit_log_format(ab, " fsuid=%d",
from_kuid(&init_user_ns, fsuid)); from_kuid(&init_user_ns, fsuid));
audit_log_format(ab, " ouid=%d", 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_format(ab, " target=");
audit_log_untrustedstring(ab, sa->aad->fs.target); audit_log_untrustedstring(ab, aad(sa)->fs.target);
} }
} }
...@@ -104,54 +104,53 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) ...@@ -104,54 +104,53 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
* Returns: %0 or error on failure * Returns: %0 or error on failure
*/ */
int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, 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) const char *target, kuid_t ouid, const char *info, int error)
{ {
int type = AUDIT_APPARMOR_AUTO; int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa; DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op);
struct apparmor_audit_data aad = {0,};
sa.type = LSM_AUDIT_DATA_TASK; 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.u.tsk = NULL;
sa.aad = &aad;
aad.op = op, if (likely(!aad(&sa)->error)) {
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)) {
u32 mask = perms->audit; u32 mask = perms->audit;
if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL)) if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
mask = 0xffff; mask = 0xffff;
/* mask off perms that are not being force audited */ /* 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; return 0;
type = AUDIT_APPARMOR_AUDIT; type = AUDIT_APPARMOR_AUDIT;
} else { } else {
/* only report permissions that were denied */ /* 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; type = AUDIT_APPARMOR_KILL;
/* quiet known rejects, assumes quiet and kill do not overlap */ /* 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_NOQUIET &&
AUDIT_MODE(profile) != AUDIT_ALL) AUDIT_MODE(profile) != AUDIT_ALL)
sa.aad->fs.request &= ~perms->quiet; aad(&sa)->fs.request &= ~perms->quiet;
if (!sa.aad->fs.request) if (!aad(&sa)->fs.request)
return COMPLAIN_MODE(profile) ? 0 : sa.aad->error; return COMPLAIN_MODE(profile) ? 0 : aad(&sa)->error;
} }
sa.aad->fs.denied = sa.aad->fs.request & ~perms->allow; aad(&sa)->fs.denied = aad(&sa)->fs.request & ~perms->allow;
return aa_audit(type, profile, gfp, &sa, file_audit_cb); return aa_audit(type, profile, &sa, file_audit_cb);
} }
/** /**
...@@ -302,8 +301,8 @@ int aa_path_perm(const char *op, struct aa_profile *profile, ...@@ -302,8 +301,8 @@ int aa_path_perm(const char *op, struct aa_profile *profile,
if (request & ~perms.allow) if (request & ~perms.allow)
error = -EACCES; error = -EACCES;
} }
error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request, name, error = aa_audit_file(profile, &perms, op, request, name, NULL,
NULL, cond->uid, info, error); cond->uid, info, error);
kfree(buffer); kfree(buffer);
return error; return error;
...@@ -430,7 +429,7 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry, ...@@ -430,7 +429,7 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
error = 0; error = 0;
audit: 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); lname, tname, cond.uid, info, error);
kfree(buffer); kfree(buffer);
kfree(buffer2); kfree(buffer2);
......
...@@ -108,34 +108,53 @@ struct apparmor_audit_data { ...@@ -108,34 +108,53 @@ struct apparmor_audit_data {
const char *name; const char *name;
const char *info; const char *info;
union { union {
void *target; /* these entries require a custom callback fn */
struct { struct {
struct aa_profile *peer;
struct {
const char *target;
u32 request;
u32 denied;
kuid_t ouid;
} fs;
};
struct {
const char *name;
long pos; long pos;
const char *ns; const char *ns;
void *target;
} iface; } iface;
struct { struct {
int rlim; int rlim;
unsigned long max; unsigned long max;
} rlim; } rlim;
struct {
const char *target;
u32 request;
u32 denied;
kuid_t ouid;
} fs;
}; };
}; };
/* define a short hand for apparmor_audit_data structure */ /* macros for dealing with apparmor_audit_data structure */
#define aad apparmor_audit_data #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 aa_audit_msg(int type, struct common_audit_data *sa,
void (*cb) (struct audit_buffer *, void *)); void (*cb) (struct audit_buffer *, void *));
int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
struct common_audit_data *sa,
void (*cb) (struct audit_buffer *, void *)); 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) static inline int complain_error(int error)
{ {
if (error == -EPERM || error == -EACCES) if (error == -EPERM || error == -EACCES)
......
...@@ -145,7 +145,7 @@ static inline u16 dfa_map_xindex(u16 mask) ...@@ -145,7 +145,7 @@ static inline u16 dfa_map_xindex(u16 mask)
dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff) dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff)
int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, 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); const char *target, kuid_t ouid, const char *info, int error);
/** /**
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
static void audit_cb(struct audit_buffer *ab, void *va) static void audit_cb(struct audit_buffer *ab, void *va)
{ {
struct common_audit_data *sa = va; struct common_audit_data *sa = va;
audit_log_format(ab, " target="); audit_log_format(ab, " peer=");
audit_log_untrustedstring(ab, sa->aad->target); audit_log_untrustedstring(ab, aad(sa)->peer->base.hname);
} }
/** /**
...@@ -40,16 +40,12 @@ static void audit_cb(struct audit_buffer *ab, void *va) ...@@ -40,16 +40,12 @@ static void audit_cb(struct audit_buffer *ab, void *va)
static int aa_audit_ptrace(struct aa_profile *profile, static int aa_audit_ptrace(struct aa_profile *profile,
struct aa_profile *target, int error) struct aa_profile *target, int error)
{ {
struct common_audit_data sa; DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
struct apparmor_audit_data aad = {0,};
sa.type = LSM_AUDIT_DATA_NONE;
sa.aad = &aad;
aad.op = OP_PTRACE;
aad.target = target;
aad.error = error;
return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_ATOMIC, &sa, aad(&sa)->peer = target;
audit_cb); aad(&sa)->error = error;
return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb);
} }
/** /**
......
...@@ -120,11 +120,9 @@ const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name, ...@@ -120,11 +120,9 @@ const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
void aa_info_message(const char *str) void aa_info_message(const char *str)
{ {
if (audit_enabled) { if (audit_enabled) {
struct common_audit_data sa; DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL);
struct apparmor_audit_data aad = {0,};
sa.type = LSM_AUDIT_DATA_NONE; aad(&sa)->info = str;
sa.aad = &aad;
aad.info = str;
aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL);
} }
printk(KERN_INFO "AppArmor: %s\n", str); printk(KERN_INFO "AppArmor: %s\n", str);
......
...@@ -504,11 +504,10 @@ static int apparmor_getprocattr(struct task_struct *task, char *name, ...@@ -504,11 +504,10 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
static int apparmor_setprocattr(struct task_struct *task, char *name, static int apparmor_setprocattr(struct task_struct *task, char *name,
void *value, size_t size) void *value, size_t size)
{ {
struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
char *command, *largs = NULL, *args = value; char *command, *largs = NULL, *args = value;
size_t arg_size; size_t arg_size;
int error; int error;
DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SETPROCATTR);
if (size == 0) if (size == 0)
return -EINVAL; return -EINVAL;
...@@ -568,12 +567,9 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, ...@@ -568,12 +567,9 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
return error; return error;
fail: fail:
sa.type = LSM_AUDIT_DATA_NONE; aad(&sa)->profile = aa_current_profile();
sa.aad = &aad; aad(&sa)->info = name;
aad.profile = aa_current_profile(); aad(&sa)->error = error = -EINVAL;
aad.op = OP_SETPROCATTR;
aad.info = name;
aad.error = error = -EINVAL;
aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL); aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
goto out; goto out;
} }
......
...@@ -588,9 +588,9 @@ static void audit_cb(struct audit_buffer *ab, void *va) ...@@ -588,9 +588,9 @@ static void audit_cb(struct audit_buffer *ab, void *va)
{ {
struct common_audit_data *sa = va; struct common_audit_data *sa = va;
if (sa->aad->iface.ns) { if (aad(sa)->iface.ns) {
audit_log_format(ab, " ns="); audit_log_format(ab, " ns=");
audit_log_untrustedstring(ab, sa->aad->iface.ns); audit_log_untrustedstring(ab, aad(sa)->iface.ns);
} }
} }
...@@ -606,22 +606,18 @@ static void audit_cb(struct audit_buffer *ab, void *va) ...@@ -606,22 +606,18 @@ static void audit_cb(struct audit_buffer *ab, void *va)
* *
* Returns: the error to be returned after audit is done * Returns: the error to be returned after audit is done
*/ */
static int audit_policy(struct aa_profile *profile, const char *op, gfp_t gfp, static int audit_policy(struct aa_profile *profile, const char *op,
const char *nsname, const char *name, const char *nsname, const char *name,
const char *info, int error) const char *info, int error)
{ {
struct common_audit_data sa; DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op);
struct apparmor_audit_data aad = {0,};
sa.type = LSM_AUDIT_DATA_NONE; aad(&sa)->iface.ns = nsname;
sa.aad = &aad; aad(&sa)->name = name;
aad.op = op; aad(&sa)->info = info;
aad.iface.ns = nsname; aad(&sa)->error = error;
aad.name = name;
aad.info = info; return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb);
aad.error = error;
return aa_audit(AUDIT_APPARMOR_STATUS, profile, gfp,
&sa, audit_cb);
} }
/** /**
...@@ -675,11 +671,11 @@ int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, ...@@ -675,11 +671,11 @@ int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns,
{ {
/* check if loading policy is locked out */ /* check if loading policy is locked out */
if (aa_g_lock_policy) if (aa_g_lock_policy)
return audit_policy(profile, op, GFP_KERNEL, NULL, NULL, return audit_policy(profile, op, NULL, NULL,
"policy_locked", -EACCES); "policy_locked", -EACCES);
if (!policy_admin_capable(ns)) if (!policy_admin_capable(ns))
return audit_policy(profile, op, GFP_KERNEL, NULL, NULL, return audit_policy(profile, op, NULL, NULL,
"not policy admin", -EACCES); "not policy admin", -EACCES);
/* TODO: add fine grained mediation of policy loads */ /* TODO: add fine grained mediation of policy loads */
...@@ -937,8 +933,8 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile, ...@@ -937,8 +933,8 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
list_del_init(&ent->list); list_del_init(&ent->list);
op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL; op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL;
audit_policy(profile, op, GFP_ATOMIC, NULL, audit_policy(profile, op, NULL, ent->new->base.hname,
ent->new->base.hname, NULL, error); NULL, error);
if (ent->old) { if (ent->old) {
__replace_profile(ent->old, ent->new, 1); __replace_profile(ent->old, ent->new, 1);
...@@ -993,7 +989,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile, ...@@ -993,7 +989,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
/* audit cause of failure */ /* audit cause of failure */
op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL; op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
fail: fail:
audit_policy(profile, op, GFP_KERNEL, ns_name, ent->new->base.hname, audit_policy(profile, op, ns_name, ent->new->base.hname,
info, error); info, error);
/* audit status that rest of profiles in the atomic set failed too */ /* audit status that rest of profiles in the atomic set failed too */
info = "valid profile in failed atomic policy load"; info = "valid profile in failed atomic policy load";
...@@ -1004,7 +1000,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile, ...@@ -1004,7 +1000,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
continue; continue;
} }
op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL; op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
audit_policy(profile, op, GFP_KERNEL, ns_name, audit_policy(profile, op, ns_name,
tmp->new->base.hname, info, error); tmp->new->base.hname, info, error);
} }
list_for_each_entry_safe(ent, tmp, &lh, list) { list_for_each_entry_safe(ent, tmp, &lh, list) {
...@@ -1079,7 +1075,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj, ...@@ -1079,7 +1075,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
} }
/* don't fail removal if audit fails */ /* don't fail removal if audit fails */
(void) audit_policy(subj, OP_PROF_RM, GFP_KERNEL, ns_name, name, info, (void) audit_policy(subj, OP_PROF_RM, ns_name, name, info,
error); error);
aa_put_ns(ns); aa_put_ns(ns);
aa_put_profile(profile); aa_put_profile(profile);
...@@ -1090,7 +1086,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj, ...@@ -1090,7 +1086,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
aa_put_ns(ns); aa_put_ns(ns);
fail: fail:
(void) audit_policy(subj, OP_PROF_RM, GFP_KERNEL, ns_name, name, info, (void) audit_policy(subj, OP_PROF_RM, ns_name, name, info,
error); error);
return error; return error;
} }
...@@ -79,13 +79,17 @@ struct aa_ext { ...@@ -79,13 +79,17 @@ struct aa_ext {
static void audit_cb(struct audit_buffer *ab, void *va) static void audit_cb(struct audit_buffer *ab, void *va)
{ {
struct common_audit_data *sa = va; struct common_audit_data *sa = va;
if (sa->aad->iface.target) {
struct aa_profile *name = sa->aad->iface.target; if (aad(sa)->iface.ns) {
audit_log_format(ab, " ns=");
audit_log_untrustedstring(ab, aad(sa)->iface.ns);
}
if (aad(sa)->iface.name) {
audit_log_format(ab, " name="); audit_log_format(ab, " name=");
audit_log_untrustedstring(ab, name->base.hname); audit_log_untrustedstring(ab, aad(sa)->iface.name);
} }
if (sa->aad->iface.pos) if (aad(sa)->iface.pos)
audit_log_format(ab, " offset=%ld", sa->aad->iface.pos); audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos);
} }
/** /**
...@@ -104,20 +108,18 @@ static int audit_iface(struct aa_profile *new, const char *ns_name, ...@@ -104,20 +108,18 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
int error) int error)
{ {
struct aa_profile *profile = __aa_current_profile(); struct aa_profile *profile = __aa_current_profile();
struct common_audit_data sa; DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL);
struct apparmor_audit_data aad = {0,};
sa.type = LSM_AUDIT_DATA_NONE;
sa.aad = &aad;
aad.iface.ns = ns_name;
if (e) if (e)
aad.iface.pos = e->pos - e->start; aad(&sa)->iface.pos = e->pos - e->start;
aad.iface.target = new; aad(&sa)->iface.ns = ns_name;
aad.name = name; if (new)
aad.info = info; aad(&sa)->iface.name = new->base.hname;
aad.error = error; else
aad(&sa)->iface.name = name;
return aa_audit(AUDIT_APPARMOR_STATUS, profile, GFP_KERNEL, &sa, aad(&sa)->info = info;
audit_cb); aad(&sa)->error = error;
return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb);
} }
void aa_loaddata_kref(struct kref *kref) void aa_loaddata_kref(struct kref *kref)
......
...@@ -35,7 +35,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) ...@@ -35,7 +35,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
struct common_audit_data *sa = va; struct common_audit_data *sa = va;
audit_log_format(ab, " rlimit=%s value=%lu", audit_log_format(ab, " rlimit=%s value=%lu",
rlim_names[sa->aad->rlim.rlim], sa->aad->rlim.max); rlim_names[aad(sa)->rlim.rlim], aad(sa)->rlim.max);
} }
/** /**
...@@ -50,17 +50,12 @@ static void audit_cb(struct audit_buffer *ab, void *va) ...@@ -50,17 +50,12 @@ static void audit_cb(struct audit_buffer *ab, void *va)
static int audit_resource(struct aa_profile *profile, unsigned int resource, static int audit_resource(struct aa_profile *profile, unsigned int resource,
unsigned long value, int error) unsigned long value, int error)
{ {
struct common_audit_data sa; DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SETRLIMIT);
struct apparmor_audit_data aad = {0,};
aad(&sa)->rlim.rlim = resource;
sa.type = LSM_AUDIT_DATA_NONE; aad(&sa)->rlim.max = value;
sa.aad = &aad; aad(&sa)->error = error;
aad.op = OP_SETRLIMIT, return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb);
aad.rlim.rlim = resource;
aad.rlim.max = value;
aad.error = error;
return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_KERNEL, &sa,
audit_cb);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment