diff --git a/include/linux/audit.h b/include/linux/audit.h index d6579df8dadf629968c704c774081fa4ef422586..9ae740936a65268548acd512062dfc5c135f477a 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -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 diff --git a/include/net/xfrm.h b/include/net/xfrm.h index a5f80bfbaaa467757f1ee4d45fe610c38622e652..760d2432be6b873bdd17a7610411c30fe31ae4e9 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -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) diff --git a/net/key/af_key.c b/net/key/af_key.c index 17b2a6927f01d522f496f09af33abcae1656a733..0241fff951378127424a6b1963a2c4f88317fc3a 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -27,7 +27,6 @@ #include #include #include -#include #include @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 6ab81b1d215ebb23f932624fc7845b6483ab36c2..36dd31c40f4ab7b0efb69a8a83a0bbe1fa22bbfd 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -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) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index d4356e6f7f9bc65fd67eeba6663b1cc9f321fa55..15734adc9367396b9593298f3da9735825c870fa 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "xfrm_hash.h" @@ -301,8 +300,8 @@ static void xfrm_timer_handler(unsigned long data) if (!err && x->id.spi) km_state_expired(x, 1, 0); - 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); out: spin_unlock(&x->lock); @@ -403,11 +402,9 @@ xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { if (xfrm_id_proto_match(x->id.proto, proto) && (err = security_xfrm_state_delete(x)) != 0) { - xfrm_audit_log(audit_info->loginuid, - audit_info->secid, - AUDIT_MAC_IPSEC_DELSA, - 0, NULL, x); - + xfrm_audit_state_delete(x, 0, + audit_info->loginuid, + audit_info->secid); return err; } } @@ -443,10 +440,9 @@ int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) spin_unlock_bh(&xfrm_state_lock); err = xfrm_state_delete(x); - xfrm_audit_log(audit_info->loginuid, - audit_info->secid, - AUDIT_MAC_IPSEC_DELSA, - err ? 0 : 1, NULL, x); + xfrm_audit_state_delete(x, err ? 0 : 1, + audit_info->loginuid, + audit_info->secid); xfrm_state_put(x); spin_lock_bh(&xfrm_state_lock); @@ -1821,3 +1817,72 @@ void __init xfrm_state_init(void) INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task); } +#ifdef CONFIG_AUDITSYSCALL +static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x, + struct audit_buffer *audit_buf) +{ + if (x->security) + audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s", + x->security->ctx_alg, x->security->ctx_doi, + x->security->ctx_str); + + switch(x->props.family) { + case AF_INET: + audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u", + NIPQUAD(x->props.saddr.a4), + NIPQUAD(x->id.daddr.a4)); + break; + case AF_INET6: + { + struct in6_addr saddr6, daddr6; + + 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; + } +} + +void +xfrm_audit_state_add(struct xfrm_state *x, 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=SAD-add res=%u",result); + xfrm_audit_common_stateinfo(x, audit_buf); + audit_log_format(audit_buf, " spi=%lu(0x%lx)", + (unsigned long)x->id.spi, (unsigned long)x->id.spi); + audit_log_end(audit_buf); +} +EXPORT_SYMBOL_GPL(xfrm_audit_state_add); + +void +xfrm_audit_state_delete(struct xfrm_state *x, 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=SAD-delete res=%u",result); + xfrm_audit_common_stateinfo(x, audit_buf); + audit_log_format(audit_buf, " spi=%lu(0x%lx)", + (unsigned long)x->id.spi, (unsigned long)x->id.spi); + audit_log_end(audit_buf); +} +EXPORT_SYMBOL_GPL(xfrm_audit_state_delete); +#endif /* CONFIG_AUDITSYSCALL */ diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 9e516f5cbb5e2bb50fde5f5ccb6398bd0c7c8274..0d81c0f2391920799316a313a8c1ff3051574910 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -30,7 +30,6 @@ #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #include #endif -#include static inline int alg_len(struct xfrm_algo *alg) { @@ -371,8 +370,8 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, else err = xfrm_state_update(x); - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x); + xfrm_audit_state_add(x, err ? 0 : 1, NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); if (err < 0) { x->km.state = XFRM_STATE_DEAD; @@ -451,8 +450,8 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, km_state_notify(x, &c); out: - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x); + xfrm_audit_state_delete(x, err ? 0 : 1, NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); xfrm_state_put(x); return err; } @@ -1067,8 +1066,8 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, * a type XFRM_MSG_UPDPOLICY - JHS */ excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; err = xfrm_policy_insert(p->dir, xp, excl); - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); + xfrm_audit_policy_add(xp, err ? 0 : 1, NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); if (err) { security_xfrm_policy_free(xp); @@ -1290,8 +1289,9 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, NETLINK_CB(skb).pid); } } else { - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); + xfrm_audit_policy_delete(xp, err ? 0 : 1, + NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); if (err != 0) goto out; @@ -1523,8 +1523,8 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, err = 0; if (up->hard) { xfrm_policy_delete(xp, p->dir); - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_DELSPD, 1, xp, NULL); + xfrm_audit_policy_delete(xp, 1, NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); } else { // reset the timers here? @@ -1559,8 +1559,8 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, if (ue->hard) { __xfrm_state_delete(x); - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_DELSA, 1, NULL, x); + xfrm_audit_state_delete(x, 1, NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); } err = 0; out: