aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c177
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}
805EXPORT_SYMBOL(xfrm_policy_byid); 806EXPORT_SYMBOL(xfrm_policy_byid);
806 807
807void xfrm_policy_flush(u8 type) 808void 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);
860int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), 869int 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);
914out: 918out:
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
1983EXPORT_SYMBOL(xfrm_bundle_ok); 1987EXPORT_SYMBOL(xfrm_bundle_ok);
1984 1988
1989#ifdef CONFIG_AUDITSYSCALL
1990/* Audit addition and deletion of SAs and ipsec policy */
1991
1992void 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
2097EXPORT_SYMBOL(xfrm_audit_log);
2098#endif /* CONFIG_AUDITSYSCALL */
2099
1985int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) 2100int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
1986{ 2101{
1987 int err = 0; 2102 int err = 0;