diff options
author | Joy Latten <latten@austin.ibm.com> | 2006-11-27 14:11:54 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-06 23:14:22 -0500 |
commit | 161a09e737f0761ca064ee6a907313402f7a54b6 (patch) | |
tree | 80fdf6dc5de73d810ef0ec811299a5ec3c5ce23e | |
parent | 95b99a670df31ca5271f503f378e5cac3aee8f5e (diff) |
audit: Add auditing to ipsec
An audit message occurs when an ipsec SA
or ipsec policy is created/deleted.
Signed-off-by: Joy Latten <latten@austin.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/audit.h | 6 | ||||
-rw-r--r-- | include/net/xfrm.h | 19 | ||||
-rw-r--r-- | kernel/auditsc.c | 6 | ||||
-rw-r--r-- | net/key/af_key.c | 27 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 120 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 17 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 33 |
7 files changed, 213 insertions, 15 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index b2ca666d9997..0e07db6cc0d0 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -101,6 +101,10 @@ | |||
101 | #define AUDIT_MAC_CIPSOV4_DEL 1408 /* NetLabel: del CIPSOv4 DOI entry */ | 101 | #define AUDIT_MAC_CIPSOV4_DEL 1408 /* NetLabel: del CIPSOv4 DOI entry */ |
102 | #define AUDIT_MAC_MAP_ADD 1409 /* NetLabel: add LSM domain mapping */ | 102 | #define AUDIT_MAC_MAP_ADD 1409 /* NetLabel: add LSM domain mapping */ |
103 | #define AUDIT_MAC_MAP_DEL 1410 /* NetLabel: del LSM domain mapping */ | 103 | #define AUDIT_MAC_MAP_DEL 1410 /* NetLabel: del LSM domain mapping */ |
104 | #define AUDIT_MAC_IPSEC_ADDSA 1411 /* Add a XFRM state */ | ||
105 | #define AUDIT_MAC_IPSEC_DELSA 1412 /* Delete a XFRM state */ | ||
106 | #define AUDIT_MAC_IPSEC_ADDSPD 1413 /* Add a XFRM policy */ | ||
107 | #define AUDIT_MAC_IPSEC_DELSPD 1414 /* Delete a XFRM policy */ | ||
104 | 108 | ||
105 | #define AUDIT_FIRST_KERN_ANOM_MSG 1700 | 109 | #define AUDIT_FIRST_KERN_ANOM_MSG 1700 |
106 | #define AUDIT_LAST_KERN_ANOM_MSG 1799 | 110 | #define AUDIT_LAST_KERN_ANOM_MSG 1799 |
@@ -377,6 +381,7 @@ extern void auditsc_get_stamp(struct audit_context *ctx, | |||
377 | struct timespec *t, unsigned int *serial); | 381 | struct timespec *t, unsigned int *serial); |
378 | extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); | 382 | extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); |
379 | extern uid_t audit_get_loginuid(struct audit_context *ctx); | 383 | extern uid_t audit_get_loginuid(struct audit_context *ctx); |
384 | extern void audit_log_task_context(struct audit_buffer *ab); | ||
380 | extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp); | 385 | extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp); |
381 | extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); | 386 | extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); |
382 | extern int audit_bprm(struct linux_binprm *bprm); | 387 | extern int audit_bprm(struct linux_binprm *bprm); |
@@ -449,6 +454,7 @@ extern int audit_n_rules; | |||
449 | #define audit_inode_update(i) do { ; } while (0) | 454 | #define audit_inode_update(i) do { ; } while (0) |
450 | #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) | 455 | #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) |
451 | #define audit_get_loginuid(c) ({ -1; }) | 456 | #define audit_get_loginuid(c) ({ -1; }) |
457 | #define audit_log_task_context(b) do { ; } while (0) | ||
452 | #define audit_ipc_obj(i) ({ 0; }) | 458 | #define audit_ipc_obj(i) ({ 0; }) |
453 | #define audit_ipc_set_perm(q,u,g,m) ({ 0; }) | 459 | #define audit_ipc_set_perm(q,u,g,m) ({ 0; }) |
454 | #define audit_bprm(p) ({ 0; }) | 460 | #define audit_bprm(p) ({ 0; }) |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 15ec19dcf9c8..f699cdcab406 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -392,6 +392,15 @@ extern int xfrm_unregister_km(struct xfrm_mgr *km); | |||
392 | 392 | ||
393 | extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2]; | 393 | extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2]; |
394 | 394 | ||
395 | /* Audit Information */ | ||
396 | struct xfrm_audit | ||
397 | { | ||
398 | uid_t loginuid; | ||
399 | u32 secid; | ||
400 | }; | ||
401 | void xfrm_audit_log(uid_t auid, u32 secid, int type, int result, | ||
402 | struct xfrm_policy *xp, struct xfrm_state *x); | ||
403 | |||
395 | static inline void xfrm_pol_hold(struct xfrm_policy *policy) | 404 | static inline void xfrm_pol_hold(struct xfrm_policy *policy) |
396 | { | 405 | { |
397 | if (likely(policy != NULL)) | 406 | if (likely(policy != NULL)) |
@@ -906,7 +915,7 @@ static inline int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **s | |||
906 | #endif | 915 | #endif |
907 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); | 916 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); |
908 | extern int xfrm_state_delete(struct xfrm_state *x); | 917 | extern int xfrm_state_delete(struct xfrm_state *x); |
909 | extern void xfrm_state_flush(u8 proto); | 918 | extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info); |
910 | extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq); | 919 | extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq); |
911 | extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq); | 920 | extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq); |
912 | extern void xfrm_replay_notify(struct xfrm_state *x, int event); | 921 | extern void xfrm_replay_notify(struct xfrm_state *x, int event); |
@@ -959,13 +968,13 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, | |||
959 | struct xfrm_selector *sel, | 968 | struct xfrm_selector *sel, |
960 | struct xfrm_sec_ctx *ctx, int delete); | 969 | struct xfrm_sec_ctx *ctx, int delete); |
961 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete); | 970 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete); |
962 | void xfrm_policy_flush(u8 type); | 971 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); |
963 | u32 xfrm_get_acqseq(void); | 972 | u32 xfrm_get_acqseq(void); |
964 | void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); | 973 | void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); |
965 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, | 974 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, |
966 | xfrm_address_t *daddr, xfrm_address_t *saddr, | 975 | xfrm_address_t *daddr, xfrm_address_t *saddr, |
967 | int create, unsigned short family); | 976 | int create, unsigned short family); |
968 | extern void xfrm_policy_flush(u8 type); | 977 | extern void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); |
969 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | 978 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); |
970 | extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, | 979 | extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, |
971 | struct flowi *fl, int family, int strict); | 980 | struct flowi *fl, int family, int strict); |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index ab97e5101232..40722e26de98 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -731,7 +731,7 @@ static inline void audit_free_context(struct audit_context *context) | |||
731 | printk(KERN_ERR "audit: freed %d contexts\n", count); | 731 | printk(KERN_ERR "audit: freed %d contexts\n", count); |
732 | } | 732 | } |
733 | 733 | ||
734 | static void audit_log_task_context(struct audit_buffer *ab) | 734 | void audit_log_task_context(struct audit_buffer *ab) |
735 | { | 735 | { |
736 | char *ctx = NULL; | 736 | char *ctx = NULL; |
737 | ssize_t len = 0; | 737 | ssize_t len = 0; |
@@ -760,6 +760,8 @@ error_path: | |||
760 | return; | 760 | return; |
761 | } | 761 | } |
762 | 762 | ||
763 | EXPORT_SYMBOL(audit_log_task_context); | ||
764 | |||
763 | static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) | 765 | static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) |
764 | { | 766 | { |
765 | char name[sizeof(tsk->comm)]; | 767 | char name[sizeof(tsk->comm)]; |
@@ -1488,6 +1490,8 @@ uid_t audit_get_loginuid(struct audit_context *ctx) | |||
1488 | return ctx ? ctx->loginuid : -1; | 1490 | return ctx ? ctx->loginuid : -1; |
1489 | } | 1491 | } |
1490 | 1492 | ||
1493 | EXPORT_SYMBOL(audit_get_loginuid); | ||
1494 | |||
1491 | /** | 1495 | /** |
1492 | * __audit_mq_open - record audit data for a POSIX MQ open | 1496 | * __audit_mq_open - record audit data for a POSIX MQ open |
1493 | * @oflag: open flag | 1497 | * @oflag: open flag |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 0e1dbfbb9b10..5dd5094659a1 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/proc_fs.h> | 27 | #include <linux/proc_fs.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <net/xfrm.h> | 29 | #include <net/xfrm.h> |
30 | #include <linux/audit.h> | ||
30 | 31 | ||
31 | #include <net/sock.h> | 32 | #include <net/sock.h> |
32 | 33 | ||
@@ -1420,6 +1421,9 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, | |||
1420 | else | 1421 | else |
1421 | err = xfrm_state_update(x); | 1422 | err = xfrm_state_update(x); |
1422 | 1423 | ||
1424 | xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, | ||
1425 | AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x); | ||
1426 | |||
1423 | if (err < 0) { | 1427 | if (err < 0) { |
1424 | x->km.state = XFRM_STATE_DEAD; | 1428 | x->km.state = XFRM_STATE_DEAD; |
1425 | __xfrm_state_put(x); | 1429 | __xfrm_state_put(x); |
@@ -1460,8 +1464,12 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
1460 | err = -EPERM; | 1464 | err = -EPERM; |
1461 | goto out; | 1465 | goto out; |
1462 | } | 1466 | } |
1463 | 1467 | ||
1464 | err = xfrm_state_delete(x); | 1468 | err = xfrm_state_delete(x); |
1469 | |||
1470 | xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, | ||
1471 | AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x); | ||
1472 | |||
1465 | if (err < 0) | 1473 | if (err < 0) |
1466 | goto out; | 1474 | goto out; |
1467 | 1475 | ||
@@ -1637,12 +1645,15 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
1637 | { | 1645 | { |
1638 | unsigned proto; | 1646 | unsigned proto; |
1639 | struct km_event c; | 1647 | struct km_event c; |
1648 | struct xfrm_audit audit_info; | ||
1640 | 1649 | ||
1641 | proto = pfkey_satype2proto(hdr->sadb_msg_satype); | 1650 | proto = pfkey_satype2proto(hdr->sadb_msg_satype); |
1642 | if (proto == 0) | 1651 | if (proto == 0) |
1643 | return -EINVAL; | 1652 | return -EINVAL; |
1644 | 1653 | ||
1645 | xfrm_state_flush(proto); | 1654 | audit_info.loginuid = audit_get_loginuid(current->audit_context); |
1655 | audit_info.secid = 0; | ||
1656 | xfrm_state_flush(proto, &audit_info); | ||
1646 | c.data.proto = proto; | 1657 | c.data.proto = proto; |
1647 | c.seq = hdr->sadb_msg_seq; | 1658 | c.seq = hdr->sadb_msg_seq; |
1648 | c.pid = hdr->sadb_msg_pid; | 1659 | c.pid = hdr->sadb_msg_pid; |
@@ -2205,6 +2216,9 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2205 | err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp, | 2216 | err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp, |
2206 | hdr->sadb_msg_type != SADB_X_SPDUPDATE); | 2217 | hdr->sadb_msg_type != SADB_X_SPDUPDATE); |
2207 | 2218 | ||
2219 | xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, | ||
2220 | AUDIT_MAC_IPSEC_ADDSPD, err ? 0 : 1, xp, NULL); | ||
2221 | |||
2208 | if (err) | 2222 | if (err) |
2209 | goto out; | 2223 | goto out; |
2210 | 2224 | ||
@@ -2282,6 +2296,10 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2282 | xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1, | 2296 | xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1, |
2283 | &sel, tmp.security, 1); | 2297 | &sel, tmp.security, 1); |
2284 | security_xfrm_policy_free(&tmp); | 2298 | security_xfrm_policy_free(&tmp); |
2299 | |||
2300 | xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, | ||
2301 | AUDIT_MAC_IPSEC_DELSPD, (xp) ? 1 : 0, xp, NULL); | ||
2302 | |||
2285 | if (xp == NULL) | 2303 | if (xp == NULL) |
2286 | return -ENOENT; | 2304 | return -ENOENT; |
2287 | 2305 | ||
@@ -2416,8 +2434,11 @@ static int key_notify_policy_flush(struct km_event *c) | |||
2416 | static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 2434 | static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
2417 | { | 2435 | { |
2418 | struct km_event c; | 2436 | struct km_event c; |
2437 | struct xfrm_audit audit_info; | ||
2419 | 2438 | ||
2420 | xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN); | 2439 | audit_info.loginuid = audit_get_loginuid(current->audit_context); |
2440 | audit_info.secid = 0; | ||
2441 | xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); | ||
2421 | c.data.type = XFRM_POLICY_TYPE_MAIN; | 2442 | c.data.type = XFRM_POLICY_TYPE_MAIN; |
2422 | c.event = XFRM_MSG_FLUSHPOLICY; | 2443 | c.event = XFRM_MSG_FLUSHPOLICY; |
2423 | c.pid = hdr->sadb_msg_pid; | 2444 | c.pid = hdr->sadb_msg_pid; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 4f04222698d9..47c13649bac1 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/cache.h> | 25 | #include <linux/cache.h> |
26 | #include <net/xfrm.h> | 26 | #include <net/xfrm.h> |
27 | #include <net/ip.h> | 27 | #include <net/ip.h> |
28 | #include <linux/audit.h> | ||
28 | 29 | ||
29 | #include "xfrm_hash.h" | 30 | #include "xfrm_hash.h" |
30 | 31 | ||
@@ -804,7 +805,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete) | |||
804 | } | 805 | } |
805 | EXPORT_SYMBOL(xfrm_policy_byid); | 806 | EXPORT_SYMBOL(xfrm_policy_byid); |
806 | 807 | ||
807 | void xfrm_policy_flush(u8 type) | 808 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) |
808 | { | 809 | { |
809 | int dir; | 810 | int dir; |
810 | 811 | ||
@@ -824,6 +825,9 @@ void xfrm_policy_flush(u8 type) | |||
824 | hlist_del(&pol->byidx); | 825 | hlist_del(&pol->byidx); |
825 | write_unlock_bh(&xfrm_policy_lock); | 826 | write_unlock_bh(&xfrm_policy_lock); |
826 | 827 | ||
828 | xfrm_audit_log(audit_info->loginuid, audit_info->secid, | ||
829 | AUDIT_MAC_IPSEC_DELSPD, 1, pol, NULL); | ||
830 | |||
827 | xfrm_policy_kill(pol); | 831 | xfrm_policy_kill(pol); |
828 | killed++; | 832 | killed++; |
829 | 833 | ||
@@ -842,6 +846,11 @@ void xfrm_policy_flush(u8 type) | |||
842 | hlist_del(&pol->byidx); | 846 | hlist_del(&pol->byidx); |
843 | write_unlock_bh(&xfrm_policy_lock); | 847 | write_unlock_bh(&xfrm_policy_lock); |
844 | 848 | ||
849 | xfrm_audit_log(audit_info->loginuid, | ||
850 | audit_info->secid, | ||
851 | AUDIT_MAC_IPSEC_DELSPD, 1, | ||
852 | pol, NULL); | ||
853 | |||
845 | xfrm_policy_kill(pol); | 854 | xfrm_policy_kill(pol); |
846 | killed++; | 855 | killed++; |
847 | 856 | ||
@@ -1977,6 +1986,115 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, | |||
1977 | 1986 | ||
1978 | EXPORT_SYMBOL(xfrm_bundle_ok); | 1987 | EXPORT_SYMBOL(xfrm_bundle_ok); |
1979 | 1988 | ||
1989 | /* Audit addition and deletion of SAs and ipsec policy */ | ||
1990 | |||
1991 | void xfrm_audit_log(uid_t auid, u32 sid, int type, int result, | ||
1992 | struct xfrm_policy *xp, struct xfrm_state *x) | ||
1993 | { | ||
1994 | |||
1995 | char *secctx; | ||
1996 | u32 secctx_len; | ||
1997 | struct xfrm_sec_ctx *sctx = NULL; | ||
1998 | struct audit_buffer *audit_buf; | ||
1999 | int family; | ||
2000 | extern int audit_enabled; | ||
2001 | |||
2002 | if (audit_enabled == 0) | ||
2003 | return; | ||
2004 | |||
2005 | audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type); | ||
2006 | if (audit_buf == NULL) | ||
2007 | return; | ||
2008 | |||
2009 | switch(type) { | ||
2010 | case AUDIT_MAC_IPSEC_ADDSA: | ||
2011 | audit_log_format(audit_buf, "SAD add: auid=%u", auid); | ||
2012 | break; | ||
2013 | case AUDIT_MAC_IPSEC_DELSA: | ||
2014 | audit_log_format(audit_buf, "SAD delete: auid=%u", auid); | ||
2015 | break; | ||
2016 | case AUDIT_MAC_IPSEC_ADDSPD: | ||
2017 | audit_log_format(audit_buf, "SPD add: auid=%u", auid); | ||
2018 | break; | ||
2019 | case AUDIT_MAC_IPSEC_DELSPD: | ||
2020 | audit_log_format(audit_buf, "SPD delete: auid=%u", auid); | ||
2021 | break; | ||
2022 | default: | ||
2023 | return; | ||
2024 | } | ||
2025 | |||
2026 | if (sid != 0 && | ||
2027 | security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) | ||
2028 | audit_log_format(audit_buf, " subj=%s", secctx); | ||
2029 | else | ||
2030 | audit_log_task_context(audit_buf); | ||
2031 | |||
2032 | if (xp) { | ||
2033 | family = xp->selector.family; | ||
2034 | if (xp->security) | ||
2035 | sctx = xp->security; | ||
2036 | } else { | ||
2037 | family = x->props.family; | ||
2038 | if (x->security) | ||
2039 | sctx = x->security; | ||
2040 | } | ||
2041 | |||
2042 | if (sctx) | ||
2043 | audit_log_format(audit_buf, | ||
2044 | " sec_alg=%u sec_doi=%u sec_obj=%s", | ||
2045 | sctx->ctx_alg, sctx->ctx_doi, sctx->ctx_str); | ||
2046 | |||
2047 | switch(family) { | ||
2048 | case AF_INET: | ||
2049 | { | ||
2050 | struct in_addr saddr, daddr; | ||
2051 | if (xp) { | ||
2052 | saddr.s_addr = xp->selector.saddr.a4; | ||
2053 | daddr.s_addr = xp->selector.daddr.a4; | ||
2054 | } else { | ||
2055 | saddr.s_addr = x->props.saddr.a4; | ||
2056 | daddr.s_addr = x->id.daddr.a4; | ||
2057 | } | ||
2058 | audit_log_format(audit_buf, | ||
2059 | " src=%u.%u.%u.%u dst=%u.%u.%u.%u", | ||
2060 | NIPQUAD(saddr), NIPQUAD(daddr)); | ||
2061 | } | ||
2062 | break; | ||
2063 | case AF_INET6: | ||
2064 | { | ||
2065 | struct in6_addr saddr6, daddr6; | ||
2066 | if (xp) { | ||
2067 | memcpy(&saddr6, xp->selector.saddr.a6, | ||
2068 | sizeof(struct in6_addr)); | ||
2069 | memcpy(&daddr6, xp->selector.daddr.a6, | ||
2070 | sizeof(struct in6_addr)); | ||
2071 | } else { | ||
2072 | memcpy(&saddr6, x->props.saddr.a6, | ||
2073 | sizeof(struct in6_addr)); | ||
2074 | memcpy(&daddr6, x->id.daddr.a6, | ||
2075 | sizeof(struct in6_addr)); | ||
2076 | } | ||
2077 | audit_log_format(audit_buf, | ||
2078 | " src=" NIP6_FMT "dst=" NIP6_FMT, | ||
2079 | NIP6(saddr6), NIP6(daddr6)); | ||
2080 | } | ||
2081 | break; | ||
2082 | } | ||
2083 | |||
2084 | if (x) | ||
2085 | audit_log_format(audit_buf, " spi=%lu(0x%lx) protocol=%s", | ||
2086 | (unsigned long)ntohl(x->id.spi), | ||
2087 | (unsigned long)ntohl(x->id.spi), | ||
2088 | x->id.proto == IPPROTO_AH ? "AH" : | ||
2089 | (x->id.proto == IPPROTO_ESP ? | ||
2090 | "ESP" : "IPCOMP")); | ||
2091 | |||
2092 | audit_log_format(audit_buf, " res=%u", result); | ||
2093 | audit_log_end(audit_buf); | ||
2094 | } | ||
2095 | |||
2096 | EXPORT_SYMBOL(xfrm_audit_log); | ||
2097 | |||
1980 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | 2098 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) |
1981 | { | 2099 | { |
1982 | int err = 0; | 2100 | int err = 0; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index a14c88bf17f0..d5d3a6f1f609 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/cache.h> | 21 | #include <linux/cache.h> |
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | #include <linux/audit.h> | ||
23 | 24 | ||
24 | #include "xfrm_hash.h" | 25 | #include "xfrm_hash.h" |
25 | 26 | ||
@@ -238,6 +239,7 @@ static void xfrm_timer_handler(unsigned long data) | |||
238 | unsigned long now = (unsigned long)xtime.tv_sec; | 239 | unsigned long now = (unsigned long)xtime.tv_sec; |
239 | long next = LONG_MAX; | 240 | long next = LONG_MAX; |
240 | int warn = 0; | 241 | int warn = 0; |
242 | int err = 0; | ||
241 | 243 | ||
242 | spin_lock(&x->lock); | 244 | spin_lock(&x->lock); |
243 | if (x->km.state == XFRM_STATE_DEAD) | 245 | if (x->km.state == XFRM_STATE_DEAD) |
@@ -295,9 +297,14 @@ expired: | |||
295 | next = 2; | 297 | next = 2; |
296 | goto resched; | 298 | goto resched; |
297 | } | 299 | } |
298 | if (!__xfrm_state_delete(x) && x->id.spi) | 300 | |
301 | err = __xfrm_state_delete(x); | ||
302 | if (!err && x->id.spi) | ||
299 | km_state_expired(x, 1, 0); | 303 | km_state_expired(x, 1, 0); |
300 | 304 | ||
305 | xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, | ||
306 | AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x); | ||
307 | |||
301 | out: | 308 | out: |
302 | spin_unlock(&x->lock); | 309 | spin_unlock(&x->lock); |
303 | } | 310 | } |
@@ -384,9 +391,10 @@ int xfrm_state_delete(struct xfrm_state *x) | |||
384 | } | 391 | } |
385 | EXPORT_SYMBOL(xfrm_state_delete); | 392 | EXPORT_SYMBOL(xfrm_state_delete); |
386 | 393 | ||
387 | void xfrm_state_flush(u8 proto) | 394 | void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) |
388 | { | 395 | { |
389 | int i; | 396 | int i; |
397 | int err = 0; | ||
390 | 398 | ||
391 | spin_lock_bh(&xfrm_state_lock); | 399 | spin_lock_bh(&xfrm_state_lock); |
392 | for (i = 0; i <= xfrm_state_hmask; i++) { | 400 | for (i = 0; i <= xfrm_state_hmask; i++) { |
@@ -400,6 +408,11 @@ restart: | |||
400 | spin_unlock_bh(&xfrm_state_lock); | 408 | spin_unlock_bh(&xfrm_state_lock); |
401 | 409 | ||
402 | xfrm_state_delete(x); | 410 | xfrm_state_delete(x); |
411 | err = xfrm_state_delete(x); | ||
412 | xfrm_audit_log(audit_info->loginuid, | ||
413 | audit_info->secid, | ||
414 | AUDIT_MAC_IPSEC_DELSA, | ||
415 | err ? 0 : 1, NULL, x); | ||
403 | xfrm_state_put(x); | 416 | xfrm_state_put(x); |
404 | 417 | ||
405 | spin_lock_bh(&xfrm_state_lock); | 418 | spin_lock_bh(&xfrm_state_lock); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 311205ffa775..e5372b11fc8f 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 31 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
32 | #include <linux/in6.h> | 32 | #include <linux/in6.h> |
33 | #endif | 33 | #endif |
34 | #include <linux/audit.h> | ||
34 | 35 | ||
35 | static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type) | 36 | static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type) |
36 | { | 37 | { |
@@ -454,6 +455,9 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | |||
454 | else | 455 | else |
455 | err = xfrm_state_update(x); | 456 | err = xfrm_state_update(x); |
456 | 457 | ||
458 | xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, | ||
459 | AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x); | ||
460 | |||
457 | if (err < 0) { | 461 | if (err < 0) { |
458 | x->km.state = XFRM_STATE_DEAD; | 462 | x->km.state = XFRM_STATE_DEAD; |
459 | __xfrm_state_put(x); | 463 | __xfrm_state_put(x); |
@@ -523,6 +527,10 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | |||
523 | } | 527 | } |
524 | 528 | ||
525 | err = xfrm_state_delete(x); | 529 | err = xfrm_state_delete(x); |
530 | |||
531 | xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, | ||
532 | AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x); | ||
533 | |||
526 | if (err < 0) | 534 | if (err < 0) |
527 | goto out; | 535 | goto out; |
528 | 536 | ||
@@ -1030,6 +1038,9 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
1030 | * a type XFRM_MSG_UPDPOLICY - JHS */ | 1038 | * a type XFRM_MSG_UPDPOLICY - JHS */ |
1031 | excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; | 1039 | excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; |
1032 | err = xfrm_policy_insert(p->dir, xp, excl); | 1040 | err = xfrm_policy_insert(p->dir, xp, excl); |
1041 | xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, | ||
1042 | AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); | ||
1043 | |||
1033 | if (err) { | 1044 | if (err) { |
1034 | security_xfrm_policy_free(xp); | 1045 | security_xfrm_policy_free(xp); |
1035 | kfree(xp); | 1046 | kfree(xp); |
@@ -1257,6 +1268,10 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
1257 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete); | 1268 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete); |
1258 | security_xfrm_policy_free(&tmp); | 1269 | security_xfrm_policy_free(&tmp); |
1259 | } | 1270 | } |
1271 | if (delete) | ||
1272 | xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, | ||
1273 | AUDIT_MAC_IPSEC_DELSPD, (xp) ? 1 : 0, xp, NULL); | ||
1274 | |||
1260 | if (xp == NULL) | 1275 | if (xp == NULL) |
1261 | return -ENOENT; | 1276 | return -ENOENT; |
1262 | 1277 | ||
@@ -1291,8 +1306,11 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma | |||
1291 | { | 1306 | { |
1292 | struct km_event c; | 1307 | struct km_event c; |
1293 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); | 1308 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); |
1309 | struct xfrm_audit audit_info; | ||
1294 | 1310 | ||
1295 | xfrm_state_flush(p->proto); | 1311 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1312 | audit_info.secid = NETLINK_CB(skb).sid; | ||
1313 | xfrm_state_flush(p->proto, &audit_info); | ||
1296 | c.data.proto = p->proto; | 1314 | c.data.proto = p->proto; |
1297 | c.event = nlh->nlmsg_type; | 1315 | c.event = nlh->nlmsg_type; |
1298 | c.seq = nlh->nlmsg_seq; | 1316 | c.seq = nlh->nlmsg_seq; |
@@ -1442,12 +1460,15 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x | |||
1442 | struct km_event c; | 1460 | struct km_event c; |
1443 | u8 type = XFRM_POLICY_TYPE_MAIN; | 1461 | u8 type = XFRM_POLICY_TYPE_MAIN; |
1444 | int err; | 1462 | int err; |
1463 | struct xfrm_audit audit_info; | ||
1445 | 1464 | ||
1446 | err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); | 1465 | err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); |
1447 | if (err) | 1466 | if (err) |
1448 | return err; | 1467 | return err; |
1449 | 1468 | ||
1450 | xfrm_policy_flush(type); | 1469 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1470 | audit_info.secid = NETLINK_CB(skb).sid; | ||
1471 | xfrm_policy_flush(type, &audit_info); | ||
1451 | c.data.type = type; | 1472 | c.data.type = type; |
1452 | c.event = nlh->nlmsg_type; | 1473 | c.event = nlh->nlmsg_type; |
1453 | c.seq = nlh->nlmsg_seq; | 1474 | c.seq = nlh->nlmsg_seq; |
@@ -1502,6 +1523,9 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void * | |||
1502 | err = 0; | 1523 | err = 0; |
1503 | if (up->hard) { | 1524 | if (up->hard) { |
1504 | xfrm_policy_delete(xp, p->dir); | 1525 | xfrm_policy_delete(xp, p->dir); |
1526 | xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, | ||
1527 | AUDIT_MAC_IPSEC_DELSPD, 1, xp, NULL); | ||
1528 | |||
1505 | } else { | 1529 | } else { |
1506 | // reset the timers here? | 1530 | // reset the timers here? |
1507 | printk("Dont know what to do with soft policy expire\n"); | 1531 | printk("Dont know what to do with soft policy expire\n"); |
@@ -1533,8 +1557,11 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void ** | |||
1533 | goto out; | 1557 | goto out; |
1534 | km_state_expired(x, ue->hard, current->pid); | 1558 | km_state_expired(x, ue->hard, current->pid); |
1535 | 1559 | ||
1536 | if (ue->hard) | 1560 | if (ue->hard) { |
1537 | __xfrm_state_delete(x); | 1561 | __xfrm_state_delete(x); |
1562 | xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, | ||
1563 | AUDIT_MAC_IPSEC_DELSA, 1, NULL, x); | ||
1564 | } | ||
1538 | out: | 1565 | out: |
1539 | spin_unlock_bh(&x->lock); | 1566 | spin_unlock_bh(&x->lock); |
1540 | xfrm_state_put(x); | 1567 | xfrm_state_put(x); |