diff options
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 64a375178c5f..157bfbd250ba 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -834,11 +834,67 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, | |||
834 | } | 834 | } |
835 | EXPORT_SYMBOL(xfrm_policy_byid); | 835 | EXPORT_SYMBOL(xfrm_policy_byid); |
836 | 836 | ||
837 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | 837 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
838 | static inline int | ||
839 | xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | ||
838 | { | 840 | { |
839 | int dir; | 841 | int dir, err = 0; |
842 | |||
843 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | ||
844 | struct xfrm_policy *pol; | ||
845 | struct hlist_node *entry; | ||
846 | int i; | ||
847 | |||
848 | hlist_for_each_entry(pol, entry, | ||
849 | &xfrm_policy_inexact[dir], bydst) { | ||
850 | if (pol->type != type) | ||
851 | continue; | ||
852 | err = security_xfrm_policy_delete(pol); | ||
853 | if (err) { | ||
854 | xfrm_audit_log(audit_info->loginuid, | ||
855 | audit_info->secid, | ||
856 | AUDIT_MAC_IPSEC_DELSPD, 0, | ||
857 | pol, NULL); | ||
858 | return err; | ||
859 | } | ||
860 | } | ||
861 | for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { | ||
862 | hlist_for_each_entry(pol, entry, | ||
863 | xfrm_policy_bydst[dir].table + i, | ||
864 | bydst) { | ||
865 | if (pol->type != type) | ||
866 | continue; | ||
867 | err = security_xfrm_policy_delete(pol); | ||
868 | if (err) { | ||
869 | xfrm_audit_log(audit_info->loginuid, | ||
870 | audit_info->secid, | ||
871 | AUDIT_MAC_IPSEC_DELSPD, | ||
872 | 0, pol, NULL); | ||
873 | return err; | ||
874 | } | ||
875 | } | ||
876 | } | ||
877 | } | ||
878 | return err; | ||
879 | } | ||
880 | #else | ||
881 | static inline int | ||
882 | xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | ||
883 | { | ||
884 | return 0; | ||
885 | } | ||
886 | #endif | ||
887 | |||
888 | int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | ||
889 | { | ||
890 | int dir, err = 0; | ||
840 | 891 | ||
841 | write_lock_bh(&xfrm_policy_lock); | 892 | write_lock_bh(&xfrm_policy_lock); |
893 | |||
894 | err = xfrm_policy_flush_secctx_check(type, audit_info); | ||
895 | if (err) | ||
896 | goto out; | ||
897 | |||
842 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | 898 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { |
843 | struct xfrm_policy *pol; | 899 | struct xfrm_policy *pol; |
844 | struct hlist_node *entry; | 900 | struct hlist_node *entry; |
@@ -891,7 +947,9 @@ void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | |||
891 | xfrm_policy_count[dir] -= killed; | 947 | xfrm_policy_count[dir] -= killed; |
892 | } | 948 | } |
893 | atomic_inc(&flow_cache_genid); | 949 | atomic_inc(&flow_cache_genid); |
950 | out: | ||
894 | write_unlock_bh(&xfrm_policy_lock); | 951 | write_unlock_bh(&xfrm_policy_lock); |
952 | return err; | ||
895 | } | 953 | } |
896 | EXPORT_SYMBOL(xfrm_policy_flush); | 954 | EXPORT_SYMBOL(xfrm_policy_flush); |
897 | 955 | ||
@@ -2583,4 +2641,3 @@ restore_state: | |||
2583 | } | 2641 | } |
2584 | EXPORT_SYMBOL(xfrm_migrate); | 2642 | EXPORT_SYMBOL(xfrm_migrate); |
2585 | #endif | 2643 | #endif |
2586 | |||