diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 12:05:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 12:05:15 -0500 |
commit | 2685b267bce34c9b66626cb11664509c32a761a5 (patch) | |
tree | ce8b4ad47b4a1aa1b0e7634298d63c4cb0ca46c5 /net/xfrm/xfrm_policy.c | |
parent | 4522d58275f124105819723e24e912c8e5bf3cdd (diff) | |
parent | 272491ef423b6976a230a998b10f46976aa91342 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (48 commits)
[NETFILTER]: Fix non-ANSI func. decl.
[TG3]: Identify Serdes devices more clearly.
[TG3]: Use msleep.
[TG3]: Use netif_msg_*.
[TG3]: Allow partial speed advertisement.
[TG3]: Add TG3_FLG2_IS_NIC flag.
[TG3]: Add 5787F device ID.
[TG3]: Fix Phy loopback.
[WANROUTER]: Kill kmalloc debugging code.
[TCP] inet_twdr_hangman: Delete unnecessary memory barrier().
[NET]: Memory barrier cleanups
[IPSEC]: Fix inetpeer leak in ipv4 xfrm dst entries.
audit: disable ipsec auditing when CONFIG_AUDITSYSCALL=n
audit: Add auditing to ipsec
[IRDA] irlan: Fix compile warning when CONFIG_PROC_FS=n
[IrDA]: Incorrect TTP header reservation
[IrDA]: PXA FIR code device model conversion
[GENETLINK]: Fix misplaced command flags.
[NETLIK]: Add a pointer to the Generic Netlink wiki page.
[IPV6] RAW: Don't release unlocked sock.
...
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 177 |
1 files changed, 146 insertions, 31 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 3f3f563eb4ab..bebd40e5a62e 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 | ||
@@ -860,33 +869,12 @@ EXPORT_SYMBOL(xfrm_policy_flush); | |||
860 | int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), | 869 | int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), |
861 | void *data) | 870 | void *data) |
862 | { | 871 | { |
863 | struct xfrm_policy *pol; | 872 | struct xfrm_policy *pol, *last = NULL; |
864 | struct hlist_node *entry; | 873 | struct hlist_node *entry; |
865 | int dir, count, error; | 874 | int dir, last_dir = 0, count, error; |
866 | 875 | ||
867 | read_lock_bh(&xfrm_policy_lock); | 876 | read_lock_bh(&xfrm_policy_lock); |
868 | count = 0; | 877 | count = 0; |
869 | for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) { | ||
870 | struct hlist_head *table = xfrm_policy_bydst[dir].table; | ||
871 | int i; | ||
872 | |||
873 | hlist_for_each_entry(pol, entry, | ||
874 | &xfrm_policy_inexact[dir], bydst) { | ||
875 | if (pol->type == type) | ||
876 | count++; | ||
877 | } | ||
878 | for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { | ||
879 | hlist_for_each_entry(pol, entry, table + i, bydst) { | ||
880 | if (pol->type == type) | ||
881 | count++; | ||
882 | } | ||
883 | } | ||
884 | } | ||
885 | |||
886 | if (count == 0) { | ||
887 | error = -ENOENT; | ||
888 | goto out; | ||
889 | } | ||
890 | 878 | ||
891 | for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) { | 879 | for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) { |
892 | struct hlist_head *table = xfrm_policy_bydst[dir].table; | 880 | struct hlist_head *table = xfrm_policy_bydst[dir].table; |
@@ -896,21 +884,37 @@ int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*) | |||
896 | &xfrm_policy_inexact[dir], bydst) { | 884 | &xfrm_policy_inexact[dir], bydst) { |
897 | if (pol->type != type) | 885 | if (pol->type != type) |
898 | continue; | 886 | continue; |
899 | error = func(pol, dir % XFRM_POLICY_MAX, --count, data); | 887 | if (last) { |
900 | if (error) | 888 | error = func(last, last_dir % XFRM_POLICY_MAX, |
901 | goto out; | 889 | count, data); |
890 | if (error) | ||
891 | goto out; | ||
892 | } | ||
893 | last = pol; | ||
894 | last_dir = dir; | ||
895 | count++; | ||
902 | } | 896 | } |
903 | for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { | 897 | for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { |
904 | hlist_for_each_entry(pol, entry, table + i, bydst) { | 898 | hlist_for_each_entry(pol, entry, table + i, bydst) { |
905 | if (pol->type != type) | 899 | if (pol->type != type) |
906 | continue; | 900 | continue; |
907 | error = func(pol, dir % XFRM_POLICY_MAX, --count, data); | 901 | if (last) { |
908 | if (error) | 902 | error = func(last, last_dir % XFRM_POLICY_MAX, |
909 | goto out; | 903 | count, data); |
904 | if (error) | ||
905 | goto out; | ||
906 | } | ||
907 | last = pol; | ||
908 | last_dir = dir; | ||
909 | count++; | ||
910 | } | 910 | } |
911 | } | 911 | } |
912 | } | 912 | } |
913 | error = 0; | 913 | if (count == 0) { |
914 | error = -ENOENT; | ||
915 | goto out; | ||
916 | } | ||
917 | error = func(last, last_dir % XFRM_POLICY_MAX, 0, data); | ||
914 | out: | 918 | out: |
915 | read_unlock_bh(&xfrm_policy_lock); | 919 | read_unlock_bh(&xfrm_policy_lock); |
916 | return error; | 920 | return error; |
@@ -1982,6 +1986,117 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, | |||
1982 | 1986 | ||
1983 | EXPORT_SYMBOL(xfrm_bundle_ok); | 1987 | EXPORT_SYMBOL(xfrm_bundle_ok); |
1984 | 1988 | ||
1989 | #ifdef CONFIG_AUDITSYSCALL | ||
1990 | /* Audit addition and deletion of SAs and ipsec policy */ | ||
1991 | |||
1992 | void xfrm_audit_log(uid_t auid, u32 sid, int type, int result, | ||
1993 | struct xfrm_policy *xp, struct xfrm_state *x) | ||
1994 | { | ||
1995 | |||
1996 | char *secctx; | ||
1997 | u32 secctx_len; | ||
1998 | struct xfrm_sec_ctx *sctx = NULL; | ||
1999 | struct audit_buffer *audit_buf; | ||
2000 | int family; | ||
2001 | extern int audit_enabled; | ||
2002 | |||
2003 | if (audit_enabled == 0) | ||
2004 | return; | ||
2005 | |||
2006 | audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type); | ||
2007 | if (audit_buf == NULL) | ||
2008 | return; | ||
2009 | |||
2010 | switch(type) { | ||
2011 | case AUDIT_MAC_IPSEC_ADDSA: | ||
2012 | audit_log_format(audit_buf, "SAD add: auid=%u", auid); | ||
2013 | break; | ||
2014 | case AUDIT_MAC_IPSEC_DELSA: | ||
2015 | audit_log_format(audit_buf, "SAD delete: auid=%u", auid); | ||
2016 | break; | ||
2017 | case AUDIT_MAC_IPSEC_ADDSPD: | ||
2018 | audit_log_format(audit_buf, "SPD add: auid=%u", auid); | ||
2019 | break; | ||
2020 | case AUDIT_MAC_IPSEC_DELSPD: | ||
2021 | audit_log_format(audit_buf, "SPD delete: auid=%u", auid); | ||
2022 | break; | ||
2023 | default: | ||
2024 | return; | ||
2025 | } | ||
2026 | |||
2027 | if (sid != 0 && | ||
2028 | security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) | ||
2029 | audit_log_format(audit_buf, " subj=%s", secctx); | ||
2030 | else | ||
2031 | audit_log_task_context(audit_buf); | ||
2032 | |||
2033 | if (xp) { | ||
2034 | family = xp->selector.family; | ||
2035 | if (xp->security) | ||
2036 | sctx = xp->security; | ||
2037 | } else { | ||
2038 | family = x->props.family; | ||
2039 | if (x->security) | ||
2040 | sctx = x->security; | ||
2041 | } | ||
2042 | |||
2043 | if (sctx) | ||
2044 | audit_log_format(audit_buf, | ||
2045 | " sec_alg=%u sec_doi=%u sec_obj=%s", | ||
2046 | sctx->ctx_alg, sctx->ctx_doi, sctx->ctx_str); | ||
2047 | |||
2048 | switch(family) { | ||
2049 | case AF_INET: | ||
2050 | { | ||
2051 | struct in_addr saddr, daddr; | ||
2052 | if (xp) { | ||
2053 | saddr.s_addr = xp->selector.saddr.a4; | ||
2054 | daddr.s_addr = xp->selector.daddr.a4; | ||
2055 | } else { | ||
2056 | saddr.s_addr = x->props.saddr.a4; | ||
2057 | daddr.s_addr = x->id.daddr.a4; | ||
2058 | } | ||
2059 | audit_log_format(audit_buf, | ||
2060 | " src=%u.%u.%u.%u dst=%u.%u.%u.%u", | ||
2061 | NIPQUAD(saddr), NIPQUAD(daddr)); | ||
2062 | } | ||
2063 | break; | ||
2064 | case AF_INET6: | ||
2065 | { | ||
2066 | struct in6_addr saddr6, daddr6; | ||
2067 | if (xp) { | ||
2068 | memcpy(&saddr6, xp->selector.saddr.a6, | ||
2069 | sizeof(struct in6_addr)); | ||
2070 | memcpy(&daddr6, xp->selector.daddr.a6, | ||
2071 | sizeof(struct in6_addr)); | ||
2072 | } else { | ||
2073 | memcpy(&saddr6, x->props.saddr.a6, | ||
2074 | sizeof(struct in6_addr)); | ||
2075 | memcpy(&daddr6, x->id.daddr.a6, | ||
2076 | sizeof(struct in6_addr)); | ||
2077 | } | ||
2078 | audit_log_format(audit_buf, | ||
2079 | " src=" NIP6_FMT "dst=" NIP6_FMT, | ||
2080 | NIP6(saddr6), NIP6(daddr6)); | ||
2081 | } | ||
2082 | break; | ||
2083 | } | ||
2084 | |||
2085 | if (x) | ||
2086 | audit_log_format(audit_buf, " spi=%lu(0x%lx) protocol=%s", | ||
2087 | (unsigned long)ntohl(x->id.spi), | ||
2088 | (unsigned long)ntohl(x->id.spi), | ||
2089 | x->id.proto == IPPROTO_AH ? "AH" : | ||
2090 | (x->id.proto == IPPROTO_ESP ? | ||
2091 | "ESP" : "IPCOMP")); | ||
2092 | |||
2093 | audit_log_format(audit_buf, " res=%u", result); | ||
2094 | audit_log_end(audit_buf); | ||
2095 | } | ||
2096 | |||
2097 | EXPORT_SYMBOL(xfrm_audit_log); | ||
2098 | #endif /* CONFIG_AUDITSYSCALL */ | ||
2099 | |||
1985 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | 2100 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) |
1986 | { | 2101 | { |
1987 | int err = 0; | 2102 | int err = 0; |