aboutsummaryrefslogtreecommitdiffstats
path: root/net/key
diff options
context:
space:
mode:
authorJamal Hadi Salim <hadi@cyberus.ca>2010-02-18 21:00:40 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-19 16:11:49 -0500
commit8be987d73481831265d7e8c648bec838271bfd9b (patch)
treed06242ca463d87e3840090959c695d9c1a151799 /net/key
parent927606a17e802fcf0c9ee82a74bc444b84726e67 (diff)
pfkey: fix SA and SP flush sequence
RFC 2367 says flushing behavior should be: 1) user space -> kernel: flush 2) kernel: flush 3) kernel -> user space: flush event to ALL listeners This is not realistic today in the presence of selinux policies which may reject the flush etc. So we make the sequence become: 1) user space -> kernel: flush 2) kernel: flush 3) kernel -> user space: flush response to originater from #1 4) if there were no errors then: kernel -> user space: flush event to ALL listeners Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/key')
-rw-r--r--net/key/af_key.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 79d2c0f3c334..b3faede9a4f6 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1712,6 +1712,23 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg
1712 return 0; 1712 return 0;
1713} 1713}
1714 1714
1715static int unicast_flush_resp(struct sock *sk, struct sadb_msg *ihdr)
1716{
1717 struct sk_buff *skb;
1718 struct sadb_msg *hdr;
1719
1720 skb = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_ATOMIC);
1721 if (!skb)
1722 return -ENOBUFS;
1723
1724 hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg));
1725 memcpy(hdr, ihdr, sizeof(struct sadb_msg));
1726 hdr->sadb_msg_errno = (uint8_t) 0;
1727 hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
1728
1729 return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk));
1730}
1731
1715static int key_notify_sa_flush(struct km_event *c) 1732static int key_notify_sa_flush(struct km_event *c)
1716{ 1733{
1717 struct sk_buff *skb; 1734 struct sk_buff *skb;
@@ -1740,7 +1757,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
1740 unsigned proto; 1757 unsigned proto;
1741 struct km_event c; 1758 struct km_event c;
1742 struct xfrm_audit audit_info; 1759 struct xfrm_audit audit_info;
1743 int err; 1760 int err, err2;
1744 1761
1745 proto = pfkey_satype2proto(hdr->sadb_msg_satype); 1762 proto = pfkey_satype2proto(hdr->sadb_msg_satype);
1746 if (proto == 0) 1763 if (proto == 0)
@@ -1750,8 +1767,10 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
1750 audit_info.sessionid = audit_get_sessionid(current); 1767 audit_info.sessionid = audit_get_sessionid(current);
1751 audit_info.secid = 0; 1768 audit_info.secid = 0;
1752 err = xfrm_state_flush(net, proto, &audit_info); 1769 err = xfrm_state_flush(net, proto, &audit_info);
1753 if (err) 1770 err2 = unicast_flush_resp(sk, hdr);
1754 return err; 1771 if (err || err2)
1772 return err ? err : err2;
1773
1755 c.data.proto = proto; 1774 c.data.proto = proto;
1756 c.seq = hdr->sadb_msg_seq; 1775 c.seq = hdr->sadb_msg_seq;
1757 c.pid = hdr->sadb_msg_pid; 1776 c.pid = hdr->sadb_msg_pid;
@@ -2706,14 +2725,16 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2706 struct net *net = sock_net(sk); 2725 struct net *net = sock_net(sk);
2707 struct km_event c; 2726 struct km_event c;
2708 struct xfrm_audit audit_info; 2727 struct xfrm_audit audit_info;
2709 int err; 2728 int err, err2;
2710 2729
2711 audit_info.loginuid = audit_get_loginuid(current); 2730 audit_info.loginuid = audit_get_loginuid(current);
2712 audit_info.sessionid = audit_get_sessionid(current); 2731 audit_info.sessionid = audit_get_sessionid(current);
2713 audit_info.secid = 0; 2732 audit_info.secid = 0;
2714 err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); 2733 err = xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info);
2715 if (err) 2734 err2 = unicast_flush_resp(sk, hdr);
2716 return err; 2735 if (err || err2)
2736 return err ? err : err2;
2737
2717 c.data.type = XFRM_POLICY_TYPE_MAIN; 2738 c.data.type = XFRM_POLICY_TYPE_MAIN;
2718 c.event = XFRM_MSG_FLUSHPOLICY; 2739 c.event = XFRM_MSG_FLUSHPOLICY;
2719 c.pid = hdr->sadb_msg_pid; 2740 c.pid = hdr->sadb_msg_pid;