diff options
author | Paul Moore <paul.moore@hp.com> | 2008-04-12 22:07:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-12 22:07:52 -0400 |
commit | 03e1ad7b5d871d4189b1da3125c2f12d1b5f7d0b (patch) | |
tree | 1e7f291ac6bd0c1f3a95e8252c32fcce7ff47ea7 /net/xfrm/xfrm_user.c | |
parent | 00447872a643787411c2c0cb1df6169dda8b0c47 (diff) |
LSM: Make the Labeled IPsec hooks more stack friendly
The xfrm_get_policy() and xfrm_add_pol_expire() put some rather large structs
on the stack to work around the LSM API. This patch attempts to fix that
problem by changing the LSM API to require only the relevant "security"
pointers instead of the entire SPD entry; we do this for all of the
security_xfrm_policy*() functions to keep things consistent.
Signed-off-by: Paul Moore <paul.moore@hp.com>
Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 5578c909fcf6..ecf9d67daef5 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -959,7 +959,7 @@ static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs | |||
959 | return 0; | 959 | return 0; |
960 | 960 | ||
961 | uctx = nla_data(rt); | 961 | uctx = nla_data(rt); |
962 | return security_xfrm_policy_alloc(pol, uctx); | 962 | return security_xfrm_policy_alloc(&pol->security, uctx); |
963 | } | 963 | } |
964 | 964 | ||
965 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, | 965 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, |
@@ -1143,7 +1143,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1143 | NETLINK_CB(skb).sid); | 1143 | NETLINK_CB(skb).sid); |
1144 | 1144 | ||
1145 | if (err) { | 1145 | if (err) { |
1146 | security_xfrm_policy_free(xp); | 1146 | security_xfrm_policy_free(xp->security); |
1147 | kfree(xp); | 1147 | kfree(xp); |
1148 | return err; | 1148 | return err; |
1149 | } | 1149 | } |
@@ -1337,22 +1337,23 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1337 | xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err); | 1337 | xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err); |
1338 | else { | 1338 | else { |
1339 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; | 1339 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
1340 | struct xfrm_policy tmp; | 1340 | struct xfrm_sec_ctx *ctx; |
1341 | 1341 | ||
1342 | err = verify_sec_ctx_len(attrs); | 1342 | err = verify_sec_ctx_len(attrs); |
1343 | if (err) | 1343 | if (err) |
1344 | return err; | 1344 | return err; |
1345 | 1345 | ||
1346 | memset(&tmp, 0, sizeof(struct xfrm_policy)); | ||
1347 | if (rt) { | 1346 | if (rt) { |
1348 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); | 1347 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); |
1349 | 1348 | ||
1350 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) | 1349 | err = security_xfrm_policy_alloc(&ctx, uctx); |
1350 | if (err) | ||
1351 | return err; | 1351 | return err; |
1352 | } | 1352 | } else |
1353 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, | 1353 | ctx = NULL; |
1354 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, ctx, | ||
1354 | delete, &err); | 1355 | delete, &err); |
1355 | security_xfrm_policy_free(&tmp); | 1356 | security_xfrm_policy_free(ctx); |
1356 | } | 1357 | } |
1357 | if (xp == NULL) | 1358 | if (xp == NULL) |
1358 | return -ENOENT; | 1359 | return -ENOENT; |
@@ -1572,26 +1573,26 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1572 | xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err); | 1573 | xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err); |
1573 | else { | 1574 | else { |
1574 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; | 1575 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
1575 | struct xfrm_policy tmp; | 1576 | struct xfrm_sec_ctx *ctx; |
1576 | 1577 | ||
1577 | err = verify_sec_ctx_len(attrs); | 1578 | err = verify_sec_ctx_len(attrs); |
1578 | if (err) | 1579 | if (err) |
1579 | return err; | 1580 | return err; |
1580 | 1581 | ||
1581 | memset(&tmp, 0, sizeof(struct xfrm_policy)); | ||
1582 | if (rt) { | 1582 | if (rt) { |
1583 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); | 1583 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); |
1584 | 1584 | ||
1585 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) | 1585 | err = security_xfrm_policy_alloc(&ctx, uctx); |
1586 | if (err) | ||
1586 | return err; | 1587 | return err; |
1587 | } | 1588 | } else |
1588 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, | 1589 | ctx = NULL; |
1589 | 0, &err); | 1590 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, ctx, 0, &err); |
1590 | security_xfrm_policy_free(&tmp); | 1591 | security_xfrm_policy_free(ctx); |
1591 | } | 1592 | } |
1592 | |||
1593 | if (xp == NULL) | 1593 | if (xp == NULL) |
1594 | return -ENOENT; | 1594 | return -ENOENT; |
1595 | |||
1595 | read_lock(&xp->lock); | 1596 | read_lock(&xp->lock); |
1596 | if (xp->dead) { | 1597 | if (xp->dead) { |
1597 | read_unlock(&xp->lock); | 1598 | read_unlock(&xp->lock); |