diff options
-rw-r--r-- | include/net/xfrm.h | 5 | ||||
-rw-r--r-- | net/key/af_key.c | 6 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 18 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 19 |
4 files changed, 30 insertions, 18 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 92a1fc46ea59..5a00aa85b756 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -988,8 +988,9 @@ extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, | |||
988 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); | 988 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); |
989 | struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, | 989 | struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, |
990 | struct xfrm_selector *sel, | 990 | struct xfrm_selector *sel, |
991 | struct xfrm_sec_ctx *ctx, int delete); | 991 | struct xfrm_sec_ctx *ctx, int delete, |
992 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete); | 992 | int *err); |
993 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err); | ||
993 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); | 994 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); |
994 | u32 xfrm_get_acqseq(void); | 995 | u32 xfrm_get_acqseq(void); |
995 | void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); | 996 | void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 1c58204d767e..3542435e9d40 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -2294,14 +2294,12 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2294 | } | 2294 | } |
2295 | 2295 | ||
2296 | xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1, | 2296 | xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1, |
2297 | &sel, tmp.security, 1); | 2297 | &sel, tmp.security, 1, &err); |
2298 | security_xfrm_policy_free(&tmp); | 2298 | security_xfrm_policy_free(&tmp); |
2299 | 2299 | ||
2300 | if (xp == NULL) | 2300 | if (xp == NULL) |
2301 | return -ENOENT; | 2301 | return -ENOENT; |
2302 | 2302 | ||
2303 | err = security_xfrm_policy_delete(xp); | ||
2304 | |||
2305 | xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, | 2303 | xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, |
2306 | AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); | 2304 | AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); |
2307 | 2305 | ||
@@ -2552,7 +2550,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2552 | return -EINVAL; | 2550 | return -EINVAL; |
2553 | 2551 | ||
2554 | xp = xfrm_policy_byid(XFRM_POLICY_TYPE_MAIN, dir, pol->sadb_x_policy_id, | 2552 | xp = xfrm_policy_byid(XFRM_POLICY_TYPE_MAIN, dir, pol->sadb_x_policy_id, |
2555 | hdr->sadb_msg_type == SADB_X_SPDDELETE2); | 2553 | hdr->sadb_msg_type == SADB_X_SPDDELETE2, &err); |
2556 | if (xp == NULL) | 2554 | if (xp == NULL) |
2557 | return -ENOENT; | 2555 | return -ENOENT; |
2558 | 2556 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 946b715db5ec..0c3a70ac5075 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -735,12 +735,14 @@ EXPORT_SYMBOL(xfrm_policy_insert); | |||
735 | 735 | ||
736 | struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, | 736 | struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, |
737 | struct xfrm_selector *sel, | 737 | struct xfrm_selector *sel, |
738 | struct xfrm_sec_ctx *ctx, int delete) | 738 | struct xfrm_sec_ctx *ctx, int delete, |
739 | int *err) | ||
739 | { | 740 | { |
740 | struct xfrm_policy *pol, *ret; | 741 | struct xfrm_policy *pol, *ret; |
741 | struct hlist_head *chain; | 742 | struct hlist_head *chain; |
742 | struct hlist_node *entry; | 743 | struct hlist_node *entry; |
743 | 744 | ||
745 | *err = 0; | ||
744 | write_lock_bh(&xfrm_policy_lock); | 746 | write_lock_bh(&xfrm_policy_lock); |
745 | chain = policy_hash_bysel(sel, sel->family, dir); | 747 | chain = policy_hash_bysel(sel, sel->family, dir); |
746 | ret = NULL; | 748 | ret = NULL; |
@@ -750,6 +752,11 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, | |||
750 | xfrm_sec_ctx_match(ctx, pol->security)) { | 752 | xfrm_sec_ctx_match(ctx, pol->security)) { |
751 | xfrm_pol_hold(pol); | 753 | xfrm_pol_hold(pol); |
752 | if (delete) { | 754 | if (delete) { |
755 | *err = security_xfrm_policy_delete(pol); | ||
756 | if (*err) { | ||
757 | write_unlock_bh(&xfrm_policy_lock); | ||
758 | return pol; | ||
759 | } | ||
753 | hlist_del(&pol->bydst); | 760 | hlist_del(&pol->bydst); |
754 | hlist_del(&pol->byidx); | 761 | hlist_del(&pol->byidx); |
755 | xfrm_policy_count[dir]--; | 762 | xfrm_policy_count[dir]--; |
@@ -768,12 +775,14 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, | |||
768 | } | 775 | } |
769 | EXPORT_SYMBOL(xfrm_policy_bysel_ctx); | 776 | EXPORT_SYMBOL(xfrm_policy_bysel_ctx); |
770 | 777 | ||
771 | struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete) | 778 | struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, |
779 | int *err) | ||
772 | { | 780 | { |
773 | struct xfrm_policy *pol, *ret; | 781 | struct xfrm_policy *pol, *ret; |
774 | struct hlist_head *chain; | 782 | struct hlist_head *chain; |
775 | struct hlist_node *entry; | 783 | struct hlist_node *entry; |
776 | 784 | ||
785 | *err = 0; | ||
777 | write_lock_bh(&xfrm_policy_lock); | 786 | write_lock_bh(&xfrm_policy_lock); |
778 | chain = xfrm_policy_byidx + idx_hash(id); | 787 | chain = xfrm_policy_byidx + idx_hash(id); |
779 | ret = NULL; | 788 | ret = NULL; |
@@ -781,6 +790,11 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete) | |||
781 | if (pol->type == type && pol->index == id) { | 790 | if (pol->type == type && pol->index == id) { |
782 | xfrm_pol_hold(pol); | 791 | xfrm_pol_hold(pol); |
783 | if (delete) { | 792 | if (delete) { |
793 | *err = security_xfrm_policy_delete(pol); | ||
794 | if (*err) { | ||
795 | write_unlock_bh(&xfrm_policy_lock); | ||
796 | return pol; | ||
797 | } | ||
784 | hlist_del(&pol->bydst); | 798 | hlist_del(&pol->bydst); |
785 | hlist_del(&pol->byidx); | 799 | hlist_del(&pol->byidx); |
786 | xfrm_policy_count[dir]--; | 800 | xfrm_policy_count[dir]--; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 956cfe0ff7f8..30c244bbd8ac 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1254,7 +1254,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1254 | return err; | 1254 | return err; |
1255 | 1255 | ||
1256 | if (p->index) | 1256 | if (p->index) |
1257 | xp = xfrm_policy_byid(type, p->dir, p->index, delete); | 1257 | xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err); |
1258 | else { | 1258 | else { |
1259 | struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; | 1259 | struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; |
1260 | struct xfrm_policy tmp; | 1260 | struct xfrm_policy tmp; |
@@ -1270,7 +1270,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1270 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) | 1270 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) |
1271 | return err; | 1271 | return err; |
1272 | } | 1272 | } |
1273 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete); | 1273 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, |
1274 | delete, &err); | ||
1274 | security_xfrm_policy_free(&tmp); | 1275 | security_xfrm_policy_free(&tmp); |
1275 | } | 1276 | } |
1276 | if (xp == NULL) | 1277 | if (xp == NULL) |
@@ -1288,8 +1289,6 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1288 | MSG_DONTWAIT); | 1289 | MSG_DONTWAIT); |
1289 | } | 1290 | } |
1290 | } else { | 1291 | } else { |
1291 | err = security_xfrm_policy_delete(xp); | ||
1292 | |||
1293 | xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, | 1292 | xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, |
1294 | AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); | 1293 | AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); |
1295 | 1294 | ||
@@ -1303,9 +1302,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1303 | km_policy_notify(xp, p->dir, &c); | 1302 | km_policy_notify(xp, p->dir, &c); |
1304 | } | 1303 | } |
1305 | 1304 | ||
1306 | xfrm_pol_put(xp); | ||
1307 | |||
1308 | out: | 1305 | out: |
1306 | xfrm_pol_put(xp); | ||
1309 | return err; | 1307 | return err; |
1310 | } | 1308 | } |
1311 | 1309 | ||
@@ -1502,7 +1500,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1502 | return err; | 1500 | return err; |
1503 | 1501 | ||
1504 | if (p->index) | 1502 | if (p->index) |
1505 | xp = xfrm_policy_byid(type, p->dir, p->index, 0); | 1503 | xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err); |
1506 | else { | 1504 | else { |
1507 | struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; | 1505 | struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; |
1508 | struct xfrm_policy tmp; | 1506 | struct xfrm_policy tmp; |
@@ -1518,13 +1516,14 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1518 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) | 1516 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) |
1519 | return err; | 1517 | return err; |
1520 | } | 1518 | } |
1521 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, 0); | 1519 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, |
1520 | 0, &err); | ||
1522 | security_xfrm_policy_free(&tmp); | 1521 | security_xfrm_policy_free(&tmp); |
1523 | } | 1522 | } |
1524 | 1523 | ||
1525 | if (xp == NULL) | 1524 | if (xp == NULL) |
1526 | return err; | 1525 | return -ENOENT; |
1527 | read_lock(&xp->lock); | 1526 | read_lock(&xp->lock); |
1528 | if (xp->dead) { | 1527 | if (xp->dead) { |
1529 | read_unlock(&xp->lock); | 1528 | read_unlock(&xp->lock); |
1530 | goto out; | 1529 | goto out; |