diff options
-rw-r--r-- | include/net/xfrm.h | 6 | ||||
-rw-r--r-- | net/key/af_key.c | 10 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 63 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 46 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 9 |
5 files changed, 121 insertions, 13 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 90185e8b335e..311f25af5e1a 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -964,7 +964,7 @@ struct xfrmk_spdinfo { | |||
964 | 964 | ||
965 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); | 965 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); |
966 | extern int xfrm_state_delete(struct xfrm_state *x); | 966 | extern int xfrm_state_delete(struct xfrm_state *x); |
967 | extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info); | 967 | extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info); |
968 | extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si); | 968 | extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si); |
969 | extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si); | 969 | extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si); |
970 | extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq); | 970 | extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq); |
@@ -1020,13 +1020,13 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, | |||
1020 | struct xfrm_sec_ctx *ctx, int delete, | 1020 | struct xfrm_sec_ctx *ctx, int delete, |
1021 | int *err); | 1021 | int *err); |
1022 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err); | 1022 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err); |
1023 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); | 1023 | int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); |
1024 | u32 xfrm_get_acqseq(void); | 1024 | u32 xfrm_get_acqseq(void); |
1025 | void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); | 1025 | void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); |
1026 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, | 1026 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, |
1027 | xfrm_address_t *daddr, xfrm_address_t *saddr, | 1027 | xfrm_address_t *daddr, xfrm_address_t *saddr, |
1028 | int create, unsigned short family); | 1028 | int create, unsigned short family); |
1029 | extern void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); | 1029 | extern int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); |
1030 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | 1030 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); |
1031 | extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, | 1031 | extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, |
1032 | struct flowi *fl, int family, int strict); | 1032 | struct flowi *fl, int family, int strict); |
diff --git a/net/key/af_key.c b/net/key/af_key.c index d302ddae580c..0f8304b0246b 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -1682,6 +1682,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
1682 | unsigned proto; | 1682 | unsigned proto; |
1683 | struct km_event c; | 1683 | struct km_event c; |
1684 | struct xfrm_audit audit_info; | 1684 | struct xfrm_audit audit_info; |
1685 | int err; | ||
1685 | 1686 | ||
1686 | proto = pfkey_satype2proto(hdr->sadb_msg_satype); | 1687 | proto = pfkey_satype2proto(hdr->sadb_msg_satype); |
1687 | if (proto == 0) | 1688 | if (proto == 0) |
@@ -1689,7 +1690,9 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
1689 | 1690 | ||
1690 | audit_info.loginuid = audit_get_loginuid(current->audit_context); | 1691 | audit_info.loginuid = audit_get_loginuid(current->audit_context); |
1691 | audit_info.secid = 0; | 1692 | audit_info.secid = 0; |
1692 | xfrm_state_flush(proto, &audit_info); | 1693 | err = xfrm_state_flush(proto, &audit_info); |
1694 | if (err) | ||
1695 | return err; | ||
1693 | c.data.proto = proto; | 1696 | c.data.proto = proto; |
1694 | c.seq = hdr->sadb_msg_seq; | 1697 | c.seq = hdr->sadb_msg_seq; |
1695 | c.pid = hdr->sadb_msg_pid; | 1698 | c.pid = hdr->sadb_msg_pid; |
@@ -2683,10 +2686,13 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2683 | { | 2686 | { |
2684 | struct km_event c; | 2687 | struct km_event c; |
2685 | struct xfrm_audit audit_info; | 2688 | struct xfrm_audit audit_info; |
2689 | int err; | ||
2686 | 2690 | ||
2687 | audit_info.loginuid = audit_get_loginuid(current->audit_context); | 2691 | audit_info.loginuid = audit_get_loginuid(current->audit_context); |
2688 | audit_info.secid = 0; | 2692 | audit_info.secid = 0; |
2689 | xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); | 2693 | err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); |
2694 | if (err) | ||
2695 | return err; | ||
2690 | c.data.type = XFRM_POLICY_TYPE_MAIN; | 2696 | c.data.type = XFRM_POLICY_TYPE_MAIN; |
2691 | c.event = XFRM_MSG_FLUSHPOLICY; | 2697 | c.event = XFRM_MSG_FLUSHPOLICY; |
2692 | c.pid = hdr->sadb_msg_pid; | 2698 | c.pid = hdr->sadb_msg_pid; |
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 | |||
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 372f06eb8bb7..85f3f43a6cca 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -391,12 +391,48 @@ int xfrm_state_delete(struct xfrm_state *x) | |||
391 | } | 391 | } |
392 | EXPORT_SYMBOL(xfrm_state_delete); | 392 | EXPORT_SYMBOL(xfrm_state_delete); |
393 | 393 | ||
394 | void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) | 394 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
395 | static inline int | ||
396 | xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | ||
395 | { | 397 | { |
396 | int i; | 398 | int i, err = 0; |
397 | int err = 0; | 399 | |
400 | for (i = 0; i <= xfrm_state_hmask; i++) { | ||
401 | struct hlist_node *entry; | ||
402 | struct xfrm_state *x; | ||
403 | |||
404 | hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { | ||
405 | if (xfrm_id_proto_match(x->id.proto, proto) && | ||
406 | (err = security_xfrm_state_delete(x)) != 0) { | ||
407 | xfrm_audit_log(audit_info->loginuid, | ||
408 | audit_info->secid, | ||
409 | AUDIT_MAC_IPSEC_DELSA, | ||
410 | 0, NULL, x); | ||
411 | |||
412 | return err; | ||
413 | } | ||
414 | } | ||
415 | } | ||
416 | |||
417 | return err; | ||
418 | } | ||
419 | #else | ||
420 | static inline int | ||
421 | xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | ||
422 | { | ||
423 | return 0; | ||
424 | } | ||
425 | #endif | ||
426 | |||
427 | int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) | ||
428 | { | ||
429 | int i, err = 0; | ||
398 | 430 | ||
399 | spin_lock_bh(&xfrm_state_lock); | 431 | spin_lock_bh(&xfrm_state_lock); |
432 | err = xfrm_state_flush_secctx_check(proto, audit_info); | ||
433 | if (err) | ||
434 | goto out; | ||
435 | |||
400 | for (i = 0; i <= xfrm_state_hmask; i++) { | 436 | for (i = 0; i <= xfrm_state_hmask; i++) { |
401 | struct hlist_node *entry; | 437 | struct hlist_node *entry; |
402 | struct xfrm_state *x; | 438 | struct xfrm_state *x; |
@@ -419,8 +455,12 @@ restart: | |||
419 | } | 455 | } |
420 | } | 456 | } |
421 | } | 457 | } |
458 | err = 0; | ||
459 | |||
460 | out: | ||
422 | spin_unlock_bh(&xfrm_state_lock); | 461 | spin_unlock_bh(&xfrm_state_lock); |
423 | wake_up(&km_waitq); | 462 | wake_up(&km_waitq); |
463 | return err; | ||
424 | } | 464 | } |
425 | EXPORT_SYMBOL(xfrm_state_flush); | 465 | EXPORT_SYMBOL(xfrm_state_flush); |
426 | 466 | ||
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b14c7e590c31..c06883bf620e 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1418,10 +1418,13 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1418 | struct km_event c; | 1418 | struct km_event c; |
1419 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); | 1419 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); |
1420 | struct xfrm_audit audit_info; | 1420 | struct xfrm_audit audit_info; |
1421 | int err; | ||
1421 | 1422 | ||
1422 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1423 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1423 | audit_info.secid = NETLINK_CB(skb).sid; | 1424 | audit_info.secid = NETLINK_CB(skb).sid; |
1424 | xfrm_state_flush(p->proto, &audit_info); | 1425 | err = xfrm_state_flush(p->proto, &audit_info); |
1426 | if (err) | ||
1427 | return err; | ||
1425 | c.data.proto = p->proto; | 1428 | c.data.proto = p->proto; |
1426 | c.event = nlh->nlmsg_type; | 1429 | c.event = nlh->nlmsg_type; |
1427 | c.seq = nlh->nlmsg_seq; | 1430 | c.seq = nlh->nlmsg_seq; |
@@ -1582,7 +1585,9 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1582 | 1585 | ||
1583 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1586 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1584 | audit_info.secid = NETLINK_CB(skb).sid; | 1587 | audit_info.secid = NETLINK_CB(skb).sid; |
1585 | xfrm_policy_flush(type, &audit_info); | 1588 | err = xfrm_policy_flush(type, &audit_info); |
1589 | if (err) | ||
1590 | return err; | ||
1586 | c.data.type = type; | 1591 | c.data.type = type; |
1587 | c.event = nlh->nlmsg_type; | 1592 | c.event = nlh->nlmsg_type; |
1588 | c.seq = nlh->nlmsg_seq; | 1593 | c.seq = nlh->nlmsg_seq; |