Skip to content

Commit

Permalink
[XFRM]: xfrm audit calls
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Joy Latten authored and David S. Miller committed Oct 10, 2007
1 parent d2e9117 commit ab5f5e8
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 177 deletions.
9 changes: 5 additions & 4 deletions include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,11 @@
#define AUDIT_MAC_CIPSOV4_DEL 1408 /* NetLabel: del CIPSOv4 DOI entry */
#define AUDIT_MAC_MAP_ADD 1409 /* NetLabel: add LSM domain mapping */
#define AUDIT_MAC_MAP_DEL 1410 /* NetLabel: del LSM domain mapping */
#define AUDIT_MAC_IPSEC_ADDSA 1411 /* Add a XFRM state */
#define AUDIT_MAC_IPSEC_DELSA 1412 /* Delete a XFRM state */
#define AUDIT_MAC_IPSEC_ADDSPD 1413 /* Add a XFRM policy */
#define AUDIT_MAC_IPSEC_DELSPD 1414 /* Delete a XFRM policy */
#define AUDIT_MAC_IPSEC_ADDSA 1411 /* Not used */
#define AUDIT_MAC_IPSEC_DELSA 1412 /* Not used */
#define AUDIT_MAC_IPSEC_ADDSPD 1413 /* Not used */
#define AUDIT_MAC_IPSEC_DELSPD 1414 /* Not used */
#define AUDIT_MAC_IPSEC_EVENT 1415 /* Audit an IPSec event */

#define AUDIT_FIRST_KERN_ANOM_MSG 1700
#define AUDIT_LAST_KERN_ANOM_MSG 1799
Expand Down
40 changes: 36 additions & 4 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/ipsec.h>
#include <linux/in6.h>
#include <linux/mutex.h>
#include <linux/audit.h>

#include <net/sock.h>
#include <net/dst.h>
Expand Down Expand Up @@ -421,15 +422,46 @@ extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
/* Audit Information */
struct xfrm_audit
{
uid_t loginuid;
u32 loginuid;
u32 secid;
};

#ifdef CONFIG_AUDITSYSCALL
extern void xfrm_audit_log(uid_t auid, u32 secid, int type, int result,
struct xfrm_policy *xp, struct xfrm_state *x);
static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
{
struct audit_buffer *audit_buf = NULL;
char *secctx;
u32 secctx_len;

audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
AUDIT_MAC_IPSEC_EVENT);
if (audit_buf == NULL)
return NULL;

audit_log_format(audit_buf, "auid=%u", auid);

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);
return audit_buf;
}

extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
u32 auid, u32 sid);
extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
u32 auid, u32 sid);
extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
u32 auid, u32 sid);
extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
u32 auid, u32 sid);
#else
#define xfrm_audit_log(a,s,t,r,p,x) do { ; } while (0)
#define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0)
#define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0)
#define xfrm_audit_state_add(x, r, a, s) do { ; } while (0)
#define xfrm_audit_state_delete(x, r, a, s) do { ; } while (0)
#endif /* CONFIG_AUDITSYSCALL */

static inline void xfrm_pol_hold(struct xfrm_policy *policy)
Expand Down
21 changes: 10 additions & 11 deletions net/key/af_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <net/xfrm.h>
#include <linux/audit.h>

#include <net/sock.h>

Expand Down Expand Up @@ -1454,8 +1453,8 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
else
err = xfrm_state_update(x);

xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x);
xfrm_audit_state_add(x, err ? 0 : 1,
audit_get_loginuid(current->audit_context), 0);

if (err < 0) {
x->km.state = XFRM_STATE_DEAD;
Expand Down Expand Up @@ -1508,8 +1507,8 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
c.event = XFRM_MSG_DELSA;
km_state_notify(x, &c);
out:
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
xfrm_audit_state_delete(x, err ? 0 : 1,
audit_get_loginuid(current->audit_context), 0);
xfrm_state_put(x);

return err;
Expand Down Expand Up @@ -2261,8 +2260,8 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
hdr->sadb_msg_type != SADB_X_SPDUPDATE);

xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
AUDIT_MAC_IPSEC_ADDSPD, err ? 0 : 1, xp, NULL);
xfrm_audit_policy_add(xp, err ? 0 : 1,
audit_get_loginuid(current->audit_context), 0);

if (err)
goto out;
Expand Down Expand Up @@ -2345,8 +2344,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
if (xp == NULL)
return -ENOENT;

xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
xfrm_audit_policy_delete(xp, err ? 0 : 1,
audit_get_loginuid(current->audit_context), 0);

if (err)
goto out;
Expand Down Expand Up @@ -2606,8 +2605,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
return -ENOENT;

if (delete) {
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
xfrm_audit_policy_delete(xp, err ? 0 : 1,
audit_get_loginuid(current->audit_context), 0);

if (err)
goto out;
Expand Down
210 changes: 77 additions & 133 deletions net/xfrm/xfrm_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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++;
Expand All @@ -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++;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit ab5f5e8

Please sign in to comment.