[XFRM]: xfrm audit calls

This patch modifies the current ipsec audit layer
by breaking it up into purpose driven audit calls.

So far, the only audit calls made are when add/delete
an SA/policy. It had been discussed to give each
key manager it's own calls to do this, but I found
there to be much redundnacy since they did the exact
same things, except for how they got auid and sid, so I
combined them. The below audit calls can be made by any
key manager. Hopefully, this is ok.

Signed-off-by: Joy Latten <latten@austin.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Joy Latten
2007-09-17 11:51:22 -07:00
committed by David S. Miller
parent d2e9117c7a
commit ab5f5e8b14
6 changed files with 218 additions and 177 deletions

View File

@ -23,7 +23,6 @@
#include <linux/netfilter.h>
#include <linux/module.h>
#include <linux/cache.h>
#include <linux/audit.h>
#include <net/xfrm.h>
#include <net/ip.h>
@ -850,10 +849,9 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
continue;
err = security_xfrm_policy_delete(pol);
if (err) {
xfrm_audit_log(audit_info->loginuid,
audit_info->secid,
AUDIT_MAC_IPSEC_DELSPD, 0,
pol, NULL);
xfrm_audit_policy_delete(pol, 0,
audit_info->loginuid,
audit_info->secid);
return err;
}
}
@ -865,10 +863,9 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info)
continue;
err = security_xfrm_policy_delete(pol);
if (err) {
xfrm_audit_log(audit_info->loginuid,
audit_info->secid,
AUDIT_MAC_IPSEC_DELSPD,
0, pol, NULL);
xfrm_audit_policy_delete(pol, 0,
audit_info->loginuid,
audit_info->secid);
return err;
}
}
@ -909,8 +906,8 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
hlist_del(&pol->byidx);
write_unlock_bh(&xfrm_policy_lock);
xfrm_audit_log(audit_info->loginuid, audit_info->secid,
AUDIT_MAC_IPSEC_DELSPD, 1, pol, NULL);
xfrm_audit_policy_delete(pol, 1, audit_info->loginuid,
audit_info->secid);
xfrm_policy_kill(pol);
killed++;
@ -930,11 +927,9 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
hlist_del(&pol->byidx);
write_unlock_bh(&xfrm_policy_lock);
xfrm_audit_log(audit_info->loginuid,
audit_info->secid,
AUDIT_MAC_IPSEC_DELSPD, 1,
pol, NULL);
xfrm_audit_policy_delete(pol, 1,
audit_info->loginuid,
audit_info->secid);
xfrm_policy_kill(pol);
killed++;
@ -2150,123 +2145,6 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
EXPORT_SYMBOL(xfrm_bundle_ok);
#ifdef CONFIG_AUDITSYSCALL
/* Audit addition and deletion of SAs and ipsec policy */
void xfrm_audit_log(uid_t auid, u32 sid, int type, int result,
struct xfrm_policy *xp, struct xfrm_state *x)
{
char *secctx;
u32 secctx_len;
struct xfrm_sec_ctx *sctx = NULL;
struct audit_buffer *audit_buf;
int family;
extern int audit_enabled;
if (audit_enabled == 0)
return;
BUG_ON((type == AUDIT_MAC_IPSEC_ADDSA ||
type == AUDIT_MAC_IPSEC_DELSA) && !x);
BUG_ON((type == AUDIT_MAC_IPSEC_ADDSPD ||
type == AUDIT_MAC_IPSEC_DELSPD) && !xp);
audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type);
if (audit_buf == NULL)
return;
switch(type) {
case AUDIT_MAC_IPSEC_ADDSA:
audit_log_format(audit_buf, "SAD add: auid=%u", auid);
break;
case AUDIT_MAC_IPSEC_DELSA:
audit_log_format(audit_buf, "SAD delete: auid=%u", auid);
break;
case AUDIT_MAC_IPSEC_ADDSPD:
audit_log_format(audit_buf, "SPD add: auid=%u", auid);
break;
case AUDIT_MAC_IPSEC_DELSPD:
audit_log_format(audit_buf, "SPD delete: auid=%u", auid);
break;
default:
return;
}
if (sid != 0 &&
security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " subj=%s", secctx);
security_release_secctx(secctx, secctx_len);
} else
audit_log_task_context(audit_buf);
if (xp) {
family = xp->selector.family;
if (xp->security)
sctx = xp->security;
} else {
family = x->props.family;
if (x->security)
sctx = x->security;
}
if (sctx)
audit_log_format(audit_buf,
" sec_alg=%u sec_doi=%u sec_obj=%s",
sctx->ctx_alg, sctx->ctx_doi, sctx->ctx_str);
switch(family) {
case AF_INET:
{
struct in_addr saddr, daddr;
if (xp) {
saddr.s_addr = xp->selector.saddr.a4;
daddr.s_addr = xp->selector.daddr.a4;
} else {
saddr.s_addr = x->props.saddr.a4;
daddr.s_addr = x->id.daddr.a4;
}
audit_log_format(audit_buf,
" src=%u.%u.%u.%u dst=%u.%u.%u.%u",
NIPQUAD(saddr), NIPQUAD(daddr));
}
break;
case AF_INET6:
{
struct in6_addr saddr6, daddr6;
if (xp) {
memcpy(&saddr6, xp->selector.saddr.a6,
sizeof(struct in6_addr));
memcpy(&daddr6, xp->selector.daddr.a6,
sizeof(struct in6_addr));
} else {
memcpy(&saddr6, x->props.saddr.a6,
sizeof(struct in6_addr));
memcpy(&daddr6, x->id.daddr.a6,
sizeof(struct in6_addr));
}
audit_log_format(audit_buf,
" src=" NIP6_FMT " dst=" NIP6_FMT,
NIP6(saddr6), NIP6(daddr6));
}
break;
}
if (x)
audit_log_format(audit_buf, " spi=%lu(0x%lx) protocol=%s",
(unsigned long)ntohl(x->id.spi),
(unsigned long)ntohl(x->id.spi),
x->id.proto == IPPROTO_AH ? "AH" :
(x->id.proto == IPPROTO_ESP ?
"ESP" : "IPCOMP"));
audit_log_format(audit_buf, " res=%u", result);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL(xfrm_audit_log);
#endif /* CONFIG_AUDITSYSCALL */
int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
{
int err = 0;
@ -2412,6 +2290,72 @@ void __init xfrm_init(void)
xfrm_input_init();
}
#ifdef CONFIG_AUDITSYSCALL
static inline void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
struct audit_buffer *audit_buf)
{
if (xp->security)
audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
xp->security->ctx_alg, xp->security->ctx_doi,
xp->security->ctx_str);
switch(xp->selector.family) {
case AF_INET:
audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
NIPQUAD(xp->selector.saddr.a4),
NIPQUAD(xp->selector.daddr.a4));
break;
case AF_INET6:
{
struct in6_addr saddr6, daddr6;
memcpy(&saddr6, xp->selector.saddr.a6,
sizeof(struct in6_addr));
memcpy(&daddr6, xp->selector.daddr.a6,
sizeof(struct in6_addr));
audit_log_format(audit_buf,
" src=" NIP6_FMT " dst=" NIP6_FMT,
NIP6(saddr6), NIP6(daddr6));
}
break;
}
}
void
xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
{
struct audit_buffer *audit_buf;
extern int audit_enabled;
if (audit_enabled == 0)
return;
audit_buf = xfrm_audit_start(sid, auid);
if (audit_buf == NULL)
return;
audit_log_format(audit_buf, " op=SPD-add res=%u", result);
xfrm_audit_common_policyinfo(xp, audit_buf);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL_GPL(xfrm_audit_policy_add);
void
xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
{
struct audit_buffer *audit_buf;
extern int audit_enabled;
if (audit_enabled == 0)
return;
audit_buf = xfrm_audit_start(sid, auid);
if (audit_buf == NULL)
return;
audit_log_format(audit_buf, " op=SPD-delete res=%u", result);
xfrm_audit_common_policyinfo(xp, audit_buf);
audit_log_end(audit_buf);
}
EXPORT_SYMBOL_GPL(xfrm_audit_policy_delete);
#endif
#ifdef CONFIG_XFRM_MIGRATE
static int xfrm_migrate_selector_match(struct xfrm_selector *sel_cmp,
struct xfrm_selector *sel_tgt)