Commit a5149bf3 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'selinux' ("struct common_audit_data" sanitizer)

Merge common_audit_data cleanup patches from Eric Paris.

This is really too late, but it's a long-overdue cleanup of the costly
wrapper functions for the security layer.

The "struct common_audit_data" is used all over in critical paths,
allocated and initialized on the stack.  And used to be much too large,
causing not only unnecessarily big stack frames but the clearing of the
(mostly useless) data was also very visible in profiles.

As a particular example, in one microbenchmark for just doing "stat()"
over files a lot, selinux_inode_permission() used 7% of the CPU time.
That's despite the fact that it doesn't actually *do* anything: it is
just a helper wrapper function in the selinux security layer.

This patch-series shrinks "struct common_audit_data" sufficiently that
code generation for these kinds of wrapper functions is improved
noticeably, and we spend much less time just initializing data that we
will never use.

The functions still get called all the time, and it still shows up at
3.5+% in my microbenchmark, but it's quite a bit lower down the list,
and much less noticeable.

* Emailed patches from Eric Paris <eparis@redhat.com>:
  lsm_audit: don't specify the audit pre/post callbacks in 'struct common_audit_data'
  SELinux: do not allocate stack space for AVC data unless needed
  SELinux: remove avd from slow_avc_audit()
  SELinux: remove avd from selinux_audit_data
  LSM: shrink the common_audit_data data union
  LSM: shrink sizeof LSM specific portion of common_audit_data
parents 3ff8f932 b61c37f5
...@@ -22,6 +22,23 @@ ...@@ -22,6 +22,23 @@
#include <linux/key.h> #include <linux/key.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
struct lsm_network_audit {
int netif;
struct sock *sk;
u16 family;
__be16 dport;
__be16 sport;
union {
struct {
__be32 daddr;
__be32 saddr;
} v4;
struct {
struct in6_addr daddr;
struct in6_addr saddr;
} v6;
} fam;
};
/* Auxiliary data to use in generating the audit record. */ /* Auxiliary data to use in generating the audit record. */
struct common_audit_data { struct common_audit_data {
...@@ -41,23 +58,7 @@ struct common_audit_data { ...@@ -41,23 +58,7 @@ struct common_audit_data {
struct path path; struct path path;
struct dentry *dentry; struct dentry *dentry;
struct inode *inode; struct inode *inode;
struct { struct lsm_network_audit *net;
int netif;
struct sock *sk;
u16 family;
__be16 dport;
__be16 sport;
union {
struct {
__be32 daddr;
__be32 saddr;
} v4;
struct {
struct in6_addr daddr;
struct in6_addr saddr;
} v6;
} fam;
} net;
int cap; int cap;
int ipc_id; int ipc_id;
struct task_struct *tsk; struct task_struct *tsk;
...@@ -72,64 +73,15 @@ struct common_audit_data { ...@@ -72,64 +73,15 @@ struct common_audit_data {
/* this union contains LSM specific data */ /* this union contains LSM specific data */
union { union {
#ifdef CONFIG_SECURITY_SMACK #ifdef CONFIG_SECURITY_SMACK
/* SMACK data */ struct smack_audit_data *smack_audit_data;
struct smack_audit_data {
const char *function;
char *subject;
char *object;
char *request;
int result;
} smack_audit_data;
#endif #endif
#ifdef CONFIG_SECURITY_SELINUX #ifdef CONFIG_SECURITY_SELINUX
/* SELinux data */ struct selinux_audit_data *selinux_audit_data;
struct {
u32 ssid;
u32 tsid;
u16 tclass;
u32 requested;
u32 audited;
u32 denied;
/*
* auditdeny is a bit tricky and unintuitive. See the
* comments in avc.c for it's meaning and usage.
*/
u32 auditdeny;
struct av_decision *avd;
int result;
} selinux_audit_data;
#endif #endif
#ifdef CONFIG_SECURITY_APPARMOR #ifdef CONFIG_SECURITY_APPARMOR
struct { struct apparmor_audit_data *apparmor_audit_data;
int error;
int op;
int type;
void *profile;
const char *name;
const char *info;
union {
void *target;
struct {
long pos;
void *target;
} iface;
struct {
int rlim;
unsigned long max;
} rlim;
struct {
const char *target;
u32 request;
u32 denied;
uid_t ouid;
} fs;
};
} apparmor_audit_data;
#endif #endif
}; }; /* per LSM data pointer union */
/* these callback will be implemented by a specific LSM */
void (*lsm_pre_audit)(struct audit_buffer *, void *);
void (*lsm_post_audit)(struct audit_buffer *, void *);
}; };
#define v4info fam.v4 #define v4info fam.v4
...@@ -146,6 +98,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -146,6 +98,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
{ memset((_d), 0, sizeof(struct common_audit_data)); \ { memset((_d), 0, sizeof(struct common_audit_data)); \
(_d)->type = LSM_AUDIT_DATA_##_t; } (_d)->type = LSM_AUDIT_DATA_##_t; }
void common_lsm_audit(struct common_audit_data *a); void common_lsm_audit(struct common_audit_data *a,
void (*pre_audit)(struct audit_buffer *, void *),
void (*post_audit)(struct audit_buffer *, void *));
#endif #endif
...@@ -115,23 +115,23 @@ static void audit_pre(struct audit_buffer *ab, void *ca) ...@@ -115,23 +115,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[sa->aad->type]);
} }
if (sa->aad.op) { if (sa->aad->op) {
audit_log_format(ab, " operation="); audit_log_format(ab, " operation=");
audit_log_string(ab, op_table[sa->aad.op]); audit_log_string(ab, op_table[sa->aad->op]);
} }
if (sa->aad.info) { if (sa->aad->info) {
audit_log_format(ab, " info="); audit_log_format(ab, " info=");
audit_log_string(ab, sa->aad.info); audit_log_string(ab, sa->aad->info);
if (sa->aad.error) if (sa->aad->error)
audit_log_format(ab, " error=%d", sa->aad.error); audit_log_format(ab, " error=%d", sa->aad->error);
} }
if (sa->aad.profile) { if (sa->aad->profile) {
struct aa_profile *profile = sa->aad.profile; struct aa_profile *profile = sa->aad->profile;
pid_t pid; pid_t pid;
rcu_read_lock(); rcu_read_lock();
pid = rcu_dereference(tsk->real_parent)->pid; pid = rcu_dereference(tsk->real_parent)->pid;
...@@ -145,9 +145,9 @@ static void audit_pre(struct audit_buffer *ab, void *ca) ...@@ -145,9 +145,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 (sa->aad->name) {
audit_log_format(ab, " name="); audit_log_format(ab, " name=");
audit_log_untrustedstring(ab, sa->aad.name); audit_log_untrustedstring(ab, sa->aad->name);
} }
} }
...@@ -159,10 +159,8 @@ static void audit_pre(struct audit_buffer *ab, void *ca) ...@@ -159,10 +159,8 @@ 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; sa->aad->type = type;
sa->lsm_pre_audit = audit_pre; common_lsm_audit(sa, audit_pre, cb);
sa->lsm_post_audit = cb;
common_lsm_audit(sa);
} }
/** /**
...@@ -184,7 +182,7 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, ...@@ -184,7 +182,7 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
BUG_ON(!profile); BUG_ON(!profile);
if (type == AUDIT_APPARMOR_AUTO) { if (type == AUDIT_APPARMOR_AUTO) {
if (likely(!sa->aad.error)) { if (likely(!sa->aad->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;
...@@ -196,21 +194,21 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, ...@@ -196,21 +194,21 @@ 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 sa->aad->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; sa->aad->profile = profile;
aa_audit_msg(type, sa, cb); aa_audit_msg(type, sa, cb);
if (sa->aad.type == AUDIT_APPARMOR_KILL) if (sa->aad->type == AUDIT_APPARMOR_KILL)
(void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current); (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current);
if (sa->aad.type == AUDIT_APPARMOR_ALLOWED) if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
return complain_error(sa->aad.error); return complain_error(sa->aad->error);
return sa->aad.error; return sa->aad->error;
} }
...@@ -64,11 +64,13 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task, ...@@ -64,11 +64,13 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task,
struct audit_cache *ent; struct audit_cache *ent;
int type = AUDIT_APPARMOR_AUTO; int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, CAP); COMMON_AUDIT_DATA_INIT(&sa, CAP);
sa.aad = &aad;
sa.tsk = task; sa.tsk = task;
sa.u.cap = cap; sa.u.cap = cap;
sa.aad.op = OP_CAPABLE; sa.aad->op = OP_CAPABLE;
sa.aad.error = error; sa.aad->error = error;
if (likely(!error)) { if (likely(!error)) {
/* test if auditing is being forced */ /* test if auditing is being forced */
......
...@@ -67,22 +67,22 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) ...@@ -67,22 +67,22 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
struct common_audit_data *sa = va; struct common_audit_data *sa = va;
uid_t fsuid = current_fsuid(); uid_t fsuid = current_fsuid();
if (sa->aad.fs.request & AA_AUDIT_FILE_MASK) { if (sa->aad->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, sa->aad->fs.request);
} }
if (sa->aad.fs.denied & AA_AUDIT_FILE_MASK) { if (sa->aad->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, sa->aad->fs.denied);
} }
if (sa->aad.fs.request & AA_AUDIT_FILE_MASK) { if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
audit_log_format(ab, " fsuid=%d", fsuid); audit_log_format(ab, " fsuid=%d", fsuid);
audit_log_format(ab, " ouid=%d", sa->aad.fs.ouid); audit_log_format(ab, " ouid=%d", sa->aad->fs.ouid);
} }
if (sa->aad.fs.target) { if (sa->aad->fs.target) {
audit_log_format(ab, " target="); audit_log_format(ab, " target=");
audit_log_untrustedstring(ab, sa->aad.fs.target); audit_log_untrustedstring(ab, sa->aad->fs.target);
} }
} }
...@@ -107,45 +107,47 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, ...@@ -107,45 +107,47 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
{ {
int type = AUDIT_APPARMOR_AUTO; int type = AUDIT_APPARMOR_AUTO;
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); COMMON_AUDIT_DATA_INIT(&sa, NONE);
sa.aad.op = op, sa.aad = &aad;
sa.aad.fs.request = request; aad.op = op,
sa.aad.name = name; aad.fs.request = request;
sa.aad.fs.target = target; aad.name = name;
sa.aad.fs.ouid = ouid; aad.fs.target = target;
sa.aad.info = info; aad.fs.ouid = ouid;
sa.aad.error = error; aad.info = info;
aad.error = error;
if (likely(!sa.aad.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; sa.aad->fs.request &= mask;
if (likely(!sa.aad.fs.request)) if (likely(!sa.aad->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; sa.aad->fs.request = sa.aad->fs.request & ~perms->allow;
if (sa.aad.fs.request & perms->kill) if (sa.aad->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 ((sa.aad->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; sa.aad->fs.request &= ~perms->quiet;
if (!sa.aad.fs.request) if (!sa.aad->fs.request)
return COMPLAIN_MODE(profile) ? 0 : sa.aad.error; return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
} }
sa.aad.fs.denied = sa.aad.fs.request & ~perms->allow; sa.aad->fs.denied = sa.aad->fs.request & ~perms->allow;
return aa_audit(type, profile, gfp, &sa, file_audit_cb); return aa_audit(type, profile, gfp, &sa, file_audit_cb);
} }
......
...@@ -103,7 +103,33 @@ enum aa_ops { ...@@ -103,7 +103,33 @@ enum aa_ops {
}; };
/* define a short hand for apparmor_audit_data portion of common_audit_data */ struct apparmor_audit_data {
int error;
int op;
int type;
void *profile;
const char *name;
const char *info;
union {
void *target;
struct {
long pos;
void *target;
} iface;
struct {
int rlim;
unsigned long max;
} rlim;
struct {
const char *target;
u32 request;
u32 denied;
uid_t ouid;
} fs;
};
};
/* define a short hand for apparmor_audit_data structure */
#define aad apparmor_audit_data #define aad apparmor_audit_data
void aa_audit_msg(int type, struct common_audit_data *sa, void aa_audit_msg(int type, struct common_audit_data *sa,
......
...@@ -26,7 +26,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) ...@@ -26,7 +26,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, " target="); audit_log_format(ab, " target=");
audit_log_untrustedstring(ab, sa->aad.target); audit_log_untrustedstring(ab, sa->aad->target);
} }
/** /**
...@@ -41,10 +41,12 @@ static int aa_audit_ptrace(struct aa_profile *profile, ...@@ -41,10 +41,12 @@ 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; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); COMMON_AUDIT_DATA_INIT(&sa, NONE);
sa.aad.op = OP_PTRACE; sa.aad = &aad;
sa.aad.target = target; aad.op = OP_PTRACE;
sa.aad.error = error; aad.target = target;
aad.error = error;
return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_ATOMIC, &sa, return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_ATOMIC, &sa,
audit_cb); audit_cb);
......
...@@ -65,8 +65,10 @@ void aa_info_message(const char *str) ...@@ -65,8 +65,10 @@ void aa_info_message(const char *str)
{ {
if (audit_enabled) { if (audit_enabled) {
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); COMMON_AUDIT_DATA_INIT(&sa, NONE);
sa.aad.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);
......
...@@ -588,10 +588,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, ...@@ -588,10 +588,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
error = aa_setprocattr_permipc(args); error = aa_setprocattr_permipc(args);
} else { } else {
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); COMMON_AUDIT_DATA_INIT(&sa, NONE);
sa.aad.op = OP_SETPROCATTR; sa.aad = &aad;
sa.aad.info = name; aad.op = OP_SETPROCATTR;
sa.aad.error = -EINVAL; aad.info = name;
aad.error = -EINVAL;
return aa_audit(AUDIT_APPARMOR_DENIED, return aa_audit(AUDIT_APPARMOR_DENIED,
__aa_current_profile(), GFP_KERNEL, __aa_current_profile(), GFP_KERNEL,
&sa, NULL); &sa, NULL);
......
...@@ -964,11 +964,13 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info, ...@@ -964,11 +964,13 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
int error) int error)
{ {
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); COMMON_AUDIT_DATA_INIT(&sa, NONE);
sa.aad.op = op; sa.aad = &aad;
sa.aad.name = name; aad.op = op;
sa.aad.info = info; aad.name = name;
sa.aad.error = error; aad.info = info;
aad.error = error;
return aa_audit(AUDIT_APPARMOR_STATUS, __aa_current_profile(), gfp, return aa_audit(AUDIT_APPARMOR_STATUS, __aa_current_profile(), gfp,
&sa, NULL); &sa, NULL);
......
...@@ -70,13 +70,13 @@ struct aa_ext { ...@@ -70,13 +70,13 @@ 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) { if (sa->aad->iface.target) {
struct aa_profile *name = sa->aad.iface.target; struct aa_profile *name = sa->aad->iface.target;
audit_log_format(ab, " name="); audit_log_format(ab, " name=");
audit_log_untrustedstring(ab, name->base.hname); audit_log_untrustedstring(ab, name->base.hname);
} }
if (sa->aad.iface.pos) if (sa->aad->iface.pos)
audit_log_format(ab, " offset=%ld", sa->aad.iface.pos); audit_log_format(ab, " offset=%ld", sa->aad->iface.pos);
} }
/** /**
...@@ -94,13 +94,15 @@ static int audit_iface(struct aa_profile *new, const char *name, ...@@ -94,13 +94,15 @@ static int audit_iface(struct aa_profile *new, const char *name,
{ {
struct aa_profile *profile = __aa_current_profile(); struct aa_profile *profile = __aa_current_profile();
struct common_audit_data sa; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); COMMON_AUDIT_DATA_INIT(&sa, NONE);
sa.aad = &aad;
if (e) if (e)
sa.aad.iface.pos = e->pos - e->start; aad.iface.pos = e->pos - e->start;
sa.aad.iface.target = new; aad.iface.target = new;
sa.aad.name = name; aad.name = name;
sa.aad.info = info; aad.info = info;
sa.aad.error = error; aad.error = error;
return aa_audit(AUDIT_APPARMOR_STATUS, profile, GFP_KERNEL, &sa, return aa_audit(AUDIT_APPARMOR_STATUS, profile, GFP_KERNEL, &sa,
audit_cb); audit_cb);
......
...@@ -34,7 +34,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) ...@@ -34,7 +34,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[sa->aad->rlim.rlim], sa->aad->rlim.max);
} }
/** /**
...@@ -50,12 +50,14 @@ static int audit_resource(struct aa_profile *profile, unsigned int resource, ...@@ -50,12 +50,14 @@ 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; struct common_audit_data sa;
struct apparmor_audit_data aad = {0,};
COMMON_AUDIT_DATA_INIT(&sa, NONE); COMMON_AUDIT_DATA_INIT(&sa, NONE);
sa.aad.op = OP_SETRLIMIT, sa.aad = &aad;
sa.aad.rlim.rlim = resource; aad.op = OP_SETRLIMIT,
sa.aad.rlim.max = value; aad.rlim.rlim = resource;
sa.aad.error = error; aad.rlim.max = value;
aad.error = error;
return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_KERNEL, &sa, return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_KERNEL, &sa,
audit_cb); audit_cb);
} }
......
...@@ -49,8 +49,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, ...@@ -49,8 +49,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (ih == NULL) if (ih == NULL)
return -EINVAL; return -EINVAL;
ad->u.net.v4info.saddr = ih->saddr; ad->u.net->v4info.saddr = ih->saddr;
ad->u.net.v4info.daddr = ih->daddr; ad->u.net->v4info.daddr = ih->daddr;
if (proto) if (proto)
*proto = ih->protocol; *proto = ih->protocol;
...@@ -64,8 +64,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, ...@@ -64,8 +64,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (th == NULL) if (th == NULL)
break; break;
ad->u.net.sport = th->source; ad->u.net->sport = th->source;
ad->u.net.dport = th->dest; ad->u.net->dport = th->dest;
break; break;
} }
case IPPROTO_UDP: { case IPPROTO_UDP: {
...@@ -73,8 +73,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, ...@@ -73,8 +73,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (uh == NULL) if (uh == NULL)
break; break;
ad->u.net.sport = uh->source; ad->u.net->sport = uh->source;
ad->u.net.dport = uh->dest; ad->u.net->dport = uh->dest;
break; break;
} }
case IPPROTO_DCCP: { case IPPROTO_DCCP: {
...@@ -82,16 +82,16 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, ...@@ -82,16 +82,16 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (dh == NULL) if (dh == NULL)
break; break;
ad->u.net.sport = dh->dccph_sport; ad->u.net->sport = dh->dccph_sport;
ad->u.net.dport = dh->dccph_dport; ad->u.net->dport = dh->dccph_dport;
break; break;
} }
case IPPROTO_SCTP: { case IPPROTO_SCTP: {
struct sctphdr *sh = sctp_hdr(skb); struct sctphdr *sh = sctp_hdr(skb);
if (sh == NULL) if (sh == NULL)
break; break;
ad->u.net.sport = sh->source; ad->u.net->sport = sh->source;
ad->u.net.dport = sh->dest; ad->u.net->dport = sh->dest;
break; break;
} }
default: default:
...@@ -119,8 +119,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -119,8 +119,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
ip6 = ipv6_hdr(skb); ip6 = ipv6_hdr(skb);
if (ip6 == NULL) if (ip6 == NULL)
return -EINVAL; return -EINVAL;
ad->u.net.v6info.saddr = ip6->saddr; ad->u.net->v6info.saddr = ip6->saddr;
ad->u.net.v6info.daddr = ip6->daddr; ad->u.net->v6info.daddr = ip6->daddr;
ret = 0; ret = 0;
/* IPv6 can have several extension header before the Transport header /* IPv6 can have several extension header before the Transport header
* skip them */ * skip them */
...@@ -140,8 +140,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -140,8 +140,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
if (th == NULL) if (th == NULL)
break; break;
ad->u.net.sport = th->source; ad->u.net->sport = th->source;
ad->u.net.dport = th->dest; ad->u.net->dport = th->dest;
break; break;
} }
case IPPROTO_UDP: { case IPPROTO_UDP: {
...@@ -151,8 +151,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -151,8 +151,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
if (uh == NULL) if (uh == NULL)
break; break;
ad->u.net.sport = uh->source; ad->u.net->sport = uh->source;
ad->u.net.dport = uh->dest; ad->u.net->dport = uh->dest;
break; break;
} }
case IPPROTO_DCCP: { case IPPROTO_DCCP: {
...@@ -162,8 +162,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -162,8 +162,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
if (dh == NULL) if (dh == NULL)
break; break;
ad->u.net.sport = dh->dccph_sport; ad->u.net->sport = dh->dccph_sport;
ad->u.net.dport = dh->dccph_dport; ad->u.net->dport = dh->dccph_dport;
break; break;
} }
case IPPROTO_SCTP: { case IPPROTO_SCTP: {
...@@ -172,8 +172,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -172,8 +172,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
if (sh == NULL) if (sh == NULL)
break; break;
ad->u.net.sport = sh->source; ad->u.net->sport = sh->source;
ad->u.net.dport = sh->dest; ad->u.net->dport = sh->dest;
break; break;
} }
default: default:
...@@ -281,8 +281,8 @@ static void dump_common_audit_data(struct audit_buffer *ab, ...@@ -281,8 +281,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
} }
break; break;
case LSM_AUDIT_DATA_NET: case LSM_AUDIT_DATA_NET:
if (a->u.net.sk) { if (a->u.net->sk) {
struct sock *sk = a->u.net.sk; struct sock *sk = a->u.net->sk;
struct unix_sock *u; struct unix_sock *u;
int len = 0; int len = 0;
char *p = NULL; char *p = NULL;
...@@ -330,29 +330,29 @@ static void dump_common_audit_data(struct audit_buffer *ab, ...@@ -330,29 +330,29 @@ static void dump_common_audit_data(struct audit_buffer *ab,
} }
} }
switch (a->u.net.family) { switch (a->u.net->family) {
case AF_INET: case AF_INET:
print_ipv4_addr(ab, a->u.net.v4info.saddr, print_ipv4_addr(ab, a->u.net->v4info.saddr,
a->u.net.sport, a->u.net->sport,
"saddr", "src"); "saddr", "src");
print_ipv4_addr(ab, a->u.net.v4info.daddr, print_ipv4_addr(ab, a->u.net->v4info.daddr,
a->u.net.dport, a->u.net->dport,
"daddr", "dest"); "daddr", "dest");
break; break;
case AF_INET6: case AF_INET6:
print_ipv6_addr(ab, &a->u.net.v6info.saddr, print_ipv6_addr(ab, &a->u.net->v6info.saddr,
a->u.net.sport, a->u.net->sport,
"saddr", "src"); "saddr", "src");
print_ipv6_addr(ab, &a->u.net.v6info.daddr, print_ipv6_addr(ab, &a->u.net->v6info.daddr,
a->u.net.dport, a->u.net->dport,
"daddr", "dest"); "daddr", "dest");
break; break;
} }
if (a->u.net.netif > 0) { if (a->u.net->netif > 0) {
struct net_device *dev; struct net_device *dev;
/* NOTE: we always use init's namespace */ /* NOTE: we always use init's namespace */
dev = dev_get_by_index(&init_net, a->u.net.netif); dev = dev_get_by_index(&init_net, a->u.net->netif);
if (dev) { if (dev) {
audit_log_format(ab, " netif=%s", dev->name); audit_log_format(ab, " netif=%s", dev->name);
dev_put(dev); dev_put(dev);
...@@ -378,11 +378,15 @@ static void dump_common_audit_data(struct audit_buffer *ab, ...@@ -378,11 +378,15 @@ static void dump_common_audit_data(struct audit_buffer *ab,
/** /**
* common_lsm_audit - generic LSM auditing function * common_lsm_audit - generic LSM auditing function
* @a: auxiliary audit data * @a: auxiliary audit data
* @pre_audit: lsm-specific pre-audit callback
* @post_audit: lsm-specific post-audit callback
* *
* setup the audit buffer for common security information * setup the audit buffer for common security information
* uses callback to print LSM specific information * uses callback to print LSM specific information
*/ */
void common_lsm_audit(struct common_audit_data *a) void common_lsm_audit(struct common_audit_data *a,
void (*pre_audit)(struct audit_buffer *, void *),
void (*post_audit)(struct audit_buffer *, void *))
{ {
struct audit_buffer *ab; struct audit_buffer *ab;
...@@ -394,13 +398,13 @@ void common_lsm_audit(struct common_audit_data *a) ...@@ -394,13 +398,13 @@ void common_lsm_audit(struct common_audit_data *a)
if (ab == NULL) if (ab == NULL)
return; return;
if (a->lsm_pre_audit) if (pre_audit)
a->lsm_pre_audit(ab, a); pre_audit(ab, a);
dump_common_audit_data(ab, a); dump_common_audit_data(ab, a);
if (a->lsm_post_audit) if (post_audit)
a->lsm_post_audit(ab, a); post_audit(ab, a);
audit_log_end(ab); audit_log_end(ab);
} }
...@@ -436,9 +436,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) ...@@ -436,9 +436,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
{ {
struct common_audit_data *ad = a; struct common_audit_data *ad = a;
audit_log_format(ab, "avc: %s ", audit_log_format(ab, "avc: %s ",
ad->selinux_audit_data.denied ? "denied" : "granted"); ad->selinux_audit_data->slad->denied ? "denied" : "granted");
avc_dump_av(ab, ad->selinux_audit_data.tclass, avc_dump_av(ab, ad->selinux_audit_data->slad->tclass,
ad->selinux_audit_data.audited); ad->selinux_audit_data->slad->audited);
audit_log_format(ab, " for "); audit_log_format(ab, " for ");
} }
...@@ -452,22 +452,25 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) ...@@ -452,22 +452,25 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
{ {
struct common_audit_data *ad = a; struct common_audit_data *ad = a;
audit_log_format(ab, " "); audit_log_format(ab, " ");
avc_dump_query(ab, ad->selinux_audit_data.ssid, avc_dump_query(ab, ad->selinux_audit_data->slad->ssid,
ad->selinux_audit_data.tsid, ad->selinux_audit_data->slad->tsid,
ad->selinux_audit_data.tclass); ad->selinux_audit_data->slad->tclass);
} }
/* This is the slow part of avc audit with big stack footprint */ /* This is the slow part of avc audit with big stack footprint */
static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
u32 requested, u32 audited, u32 denied, u32 requested, u32 audited, u32 denied,
struct av_decision *avd, struct common_audit_data *a, struct common_audit_data *a,
unsigned flags) unsigned flags)
{ {
struct common_audit_data stack_data; struct common_audit_data stack_data;
struct selinux_audit_data sad = {0,};
struct selinux_late_audit_data slad;
if (!a) { if (!a) {
a = &stack_data; a = &stack_data;
COMMON_AUDIT_DATA_INIT(a, NONE); COMMON_AUDIT_DATA_INIT(a, NONE);
a->selinux_audit_data = &sad;
} }
/* /*
...@@ -481,15 +484,15 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, ...@@ -481,15 +484,15 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
(flags & MAY_NOT_BLOCK)) (flags & MAY_NOT_BLOCK))
return -ECHILD; return -ECHILD;
a->selinux_audit_data.tclass = tclass; slad.tclass = tclass;
a->selinux_audit_data.requested = requested; slad.requested = requested;
a->selinux_audit_data.ssid = ssid; slad.ssid = ssid;
a->selinux_audit_data.tsid = tsid; slad.tsid = tsid;
a->selinux_audit_data.audited = audited; slad.audited = audited;
a->selinux_audit_data.denied = denied; slad.denied = denied;
a->lsm_pre_audit = avc_audit_pre_callback;
a->lsm_post_audit = avc_audit_post_callback; a->selinux_audit_data->slad = &slad;
common_lsm_audit(a); common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback);
return 0; return 0;
} }
...@@ -523,7 +526,7 @@ inline int avc_audit(u32 ssid, u32 tsid, ...@@ -523,7 +526,7 @@ inline int avc_audit(u32 ssid, u32 tsid,
if (unlikely(denied)) { if (unlikely(denied)) {
audited = denied & avd->auditdeny; audited = denied & avd->auditdeny;
/* /*
* a->selinux_audit_data.auditdeny is TRICKY! Setting a bit in * a->selinux_audit_data->auditdeny is TRICKY! Setting a bit in
* this field means that ANY denials should NOT be audited if * this field means that ANY denials should NOT be audited if
* the policy contains an explicit dontaudit rule for that * the policy contains an explicit dontaudit rule for that
* permission. Take notice that this is unrelated to the * permission. Take notice that this is unrelated to the
...@@ -532,15 +535,15 @@ inline int avc_audit(u32 ssid, u32 tsid, ...@@ -532,15 +535,15 @@ inline int avc_audit(u32 ssid, u32 tsid,
* *
* denied == READ * denied == READ
* avd.auditdeny & ACCESS == 0 (not set means explicit rule) * avd.auditdeny & ACCESS == 0 (not set means explicit rule)
* selinux_audit_data.auditdeny & ACCESS == 1 * selinux_audit_data->auditdeny & ACCESS == 1
* *
* We will NOT audit the denial even though the denied * We will NOT audit the denial even though the denied
* permission was READ and the auditdeny checks were for * permission was READ and the auditdeny checks were for
* ACCESS * ACCESS
*/ */
if (a && if (a &&
a->selinux_audit_data.auditdeny && a->selinux_audit_data->auditdeny &&
!(a->selinux_audit_data.auditdeny & avd->auditdeny)) !(a->selinux_audit_data->auditdeny & avd->auditdeny))
audited = 0; audited = 0;
} else if (result) } else if (result)
audited = denied = requested; audited = denied = requested;
...@@ -551,7 +554,7 @@ inline int avc_audit(u32 ssid, u32 tsid, ...@@ -551,7 +554,7 @@ inline int avc_audit(u32 ssid, u32 tsid,
return slow_avc_audit(ssid, tsid, tclass, return slow_avc_audit(ssid, tsid, tclass,
requested, audited, denied, requested, audited, denied,
avd, a, flags); a, flags);
} }
/** /**
......
This diff is collapsed.
...@@ -46,6 +46,31 @@ struct avc_cache_stats { ...@@ -46,6 +46,31 @@ struct avc_cache_stats {
unsigned int frees; unsigned int frees;
}; };
/*
* We only need this data after we have decided to send an audit message.
*/
struct selinux_late_audit_data {
u32 ssid;
u32 tsid;
u16 tclass;
u32 requested;
u32 audited;
u32 denied;
int result;
};
/*
* We collect this at the beginning or during an selinux security operation
*/
struct selinux_audit_data {
/*
* auditdeny is a bit tricky and unintuitive. See the
* comments in avc.c for it's meaning and usage.
*/
u32 auditdeny;
struct selinux_late_audit_data *slad;
};
/* /*
* AVC operations * AVC operations
*/ */
......
...@@ -185,6 +185,15 @@ struct smack_known { ...@@ -185,6 +185,15 @@ struct smack_known {
*/ */
#define SMK_NUM_ACCESS_TYPE 5 #define SMK_NUM_ACCESS_TYPE 5
/* SMACK data */
struct smack_audit_data {
const char *function;
char *subject;
char *object;
char *request;
int result;
};
/* /*
* Smack audit data; is empty if CONFIG_AUDIT not set * Smack audit data; is empty if CONFIG_AUDIT not set
* to save some stack * to save some stack
...@@ -192,6 +201,7 @@ struct smack_known { ...@@ -192,6 +201,7 @@ struct smack_known {
struct smk_audit_info { struct smk_audit_info {
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
struct common_audit_data a; struct common_audit_data a;
struct smack_audit_data sad;
#endif #endif
}; };
/* /*
...@@ -311,7 +321,16 @@ static inline void smk_ad_init(struct smk_audit_info *a, const char *func, ...@@ -311,7 +321,16 @@ static inline void smk_ad_init(struct smk_audit_info *a, const char *func,
{ {
memset(a, 0, sizeof(*a)); memset(a, 0, sizeof(*a));
a->a.type = type; a->a.type = type;
a->a.smack_audit_data.function = func; a->a.smack_audit_data = &a->sad;
a->a.smack_audit_data->function = func;
}
static inline void smk_ad_init_net(struct smk_audit_info *a, const char *func,
char type, struct lsm_network_audit *net)
{
smk_ad_init(a, func, type);
memset(net, 0, sizeof(*net));
a->a.u.net = net;
} }
static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a,
...@@ -337,7 +356,7 @@ static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, ...@@ -337,7 +356,7 @@ static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
struct sock *sk) struct sock *sk)
{ {
a->a.u.net.sk = sk; a->a.u.net->sk = sk;
} }
#else /* no AUDIT */ #else /* no AUDIT */
......
...@@ -275,9 +275,9 @@ static inline void smack_str_from_perm(char *string, int access) ...@@ -275,9 +275,9 @@ static inline void smack_str_from_perm(char *string, int access)
static void smack_log_callback(struct audit_buffer *ab, void *a) static void smack_log_callback(struct audit_buffer *ab, void *a)
{ {
struct common_audit_data *ad = a; struct common_audit_data *ad = a;
struct smack_audit_data *sad = &ad->smack_audit_data; struct smack_audit_data *sad = ad->smack_audit_data;
audit_log_format(ab, "lsm=SMACK fn=%s action=%s", audit_log_format(ab, "lsm=SMACK fn=%s action=%s",
ad->smack_audit_data.function, ad->smack_audit_data->function,
sad->result ? "denied" : "granted"); sad->result ? "denied" : "granted");
audit_log_format(ab, " subject="); audit_log_format(ab, " subject=");
audit_log_untrustedstring(ab, sad->subject); audit_log_untrustedstring(ab, sad->subject);
...@@ -310,19 +310,19 @@ void smack_log(char *subject_label, char *object_label, int request, ...@@ -310,19 +310,19 @@ void smack_log(char *subject_label, char *object_label, int request,
if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
return; return;
if (a->smack_audit_data.function == NULL) sad = a->smack_audit_data;
a->smack_audit_data.function = "unknown";
if (sad->function == NULL)
sad->function = "unknown";
/* end preparing the audit data */ /* end preparing the audit data */
sad = &a->smack_audit_data;
smack_str_from_perm(request_buffer, request); smack_str_from_perm(request_buffer, request);
sad->subject = subject_label; sad->subject = subject_label;
sad->object = object_label; sad->object = object_label;
sad->request = request_buffer; sad->request = request_buffer;
sad->result = result; sad->result = result;
a->lsm_pre_audit = smack_log_callback;
common_lsm_audit(a); common_lsm_audit(a, smack_log_callback, NULL);
} }
#else /* #ifdef CONFIG_AUDIT */ #else /* #ifdef CONFIG_AUDIT */
void smack_log(char *subject_label, char *object_label, int request, void smack_log(char *subject_label, char *object_label, int request,
......
...@@ -1939,16 +1939,17 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) ...@@ -1939,16 +1939,17 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
char *hostsp; char *hostsp;
struct socket_smack *ssp = sk->sk_security; struct socket_smack *ssp = sk->sk_security;
struct smk_audit_info ad; struct smk_audit_info ad;
struct lsm_network_audit net;
rcu_read_lock(); rcu_read_lock();
hostsp = smack_host_label(sap); hostsp = smack_host_label(sap);
if (hostsp != NULL) { if (hostsp != NULL) {
sk_lbl = SMACK_UNLABELED_SOCKET; sk_lbl = SMACK_UNLABELED_SOCKET;
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
ad.a.u.net.family = sap->sin_family; ad.a.u.net->family = sap->sin_family;
ad.a.u.net.dport = sap->sin_port; ad.a.u.net->dport = sap->sin_port;
ad.a.u.net.v4info.daddr = sap->sin_addr.s_addr; ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
#endif #endif
rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad);
} else { } else {
...@@ -2808,9 +2809,10 @@ static int smack_unix_stream_connect(struct sock *sock, ...@@ -2808,9 +2809,10 @@ static int smack_unix_stream_connect(struct sock *sock,
struct socket_smack *osp = other->sk_security; struct socket_smack *osp = other->sk_security;
struct socket_smack *nsp = newsk->sk_security; struct socket_smack *nsp = newsk->sk_security;
struct smk_audit_info ad; struct smk_audit_info ad;
struct lsm_network_audit net;
int rc = 0; int rc = 0;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
smk_ad_setfield_u_net_sk(&ad, other); smk_ad_setfield_u_net_sk(&ad, other);
if (!capable(CAP_MAC_OVERRIDE)) if (!capable(CAP_MAC_OVERRIDE))
...@@ -2840,9 +2842,10 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) ...@@ -2840,9 +2842,10 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
struct socket_smack *ssp = sock->sk->sk_security; struct socket_smack *ssp = sock->sk->sk_security;
struct socket_smack *osp = other->sk->sk_security; struct socket_smack *osp = other->sk->sk_security;
struct smk_audit_info ad; struct smk_audit_info ad;
struct lsm_network_audit net;
int rc = 0; int rc = 0;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
smk_ad_setfield_u_net_sk(&ad, other->sk); smk_ad_setfield_u_net_sk(&ad, other->sk);
if (!capable(CAP_MAC_OVERRIDE)) if (!capable(CAP_MAC_OVERRIDE))
...@@ -2990,6 +2993,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -2990,6 +2993,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
char *csp; char *csp;
int rc; int rc;
struct smk_audit_info ad; struct smk_audit_info ad;
struct lsm_network_audit net;
if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
return 0; return 0;
...@@ -3007,9 +3011,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -3007,9 +3011,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
netlbl_secattr_destroy(&secattr); netlbl_secattr_destroy(&secattr);
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
ad.a.u.net.family = sk->sk_family; ad.a.u.net->family = sk->sk_family;
ad.a.u.net.netif = skb->skb_iif; ad.a.u.net->netif = skb->skb_iif;
ipv4_skb_to_auditdata(skb, &ad.a, NULL); ipv4_skb_to_auditdata(skb, &ad.a, NULL);
#endif #endif
/* /*
...@@ -3152,6 +3156,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, ...@@ -3152,6 +3156,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
char *sp; char *sp;
int rc; int rc;
struct smk_audit_info ad; struct smk_audit_info ad;
struct lsm_network_audit net;
/* handle mapped IPv4 packets arriving via IPv6 sockets */ /* handle mapped IPv4 packets arriving via IPv6 sockets */
if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
...@@ -3166,9 +3171,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, ...@@ -3166,9 +3171,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
netlbl_secattr_destroy(&secattr); netlbl_secattr_destroy(&secattr);
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
ad.a.u.net.family = family; ad.a.u.net->family = family;
ad.a.u.net.netif = skb->skb_iif; ad.a.u.net->netif = skb->skb_iif;
ipv4_skb_to_auditdata(skb, &ad.a, NULL); ipv4_skb_to_auditdata(skb, &ad.a, NULL);
#endif #endif
/* /*
......
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