X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=net%2Fxfrm%2Fxfrm_policy.c;h=0c3a70ac507545e6afef5d282c0460560e0ecdb5;hb=3dfb737998c265d3c8a15b931dc4d72335ab8255;hp=fa7ce060b454ea9c01343d38b7c1ebcde96d1c2c;hpb=d27146dd5b72ab7d7e641f56f4bee1484dabd0b7;p=linux-2.6-omap-h63xx.git diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index fa7ce060b45..0c3a70ac507 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1,4 +1,4 @@ -/* +/* * xfrm_policy.c * * Changes: @@ -151,7 +151,7 @@ retry: return type; } -int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, +int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family) { struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family); @@ -262,7 +262,7 @@ static inline unsigned long make_jiffies(long secs) if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ) return MAX_SCHEDULE_TIMEOUT-1; else - return secs*HZ; + return secs*HZ; } static void xfrm_policy_timer(unsigned long data) @@ -735,12 +735,14 @@ EXPORT_SYMBOL(xfrm_policy_insert); struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, struct xfrm_selector *sel, - struct xfrm_sec_ctx *ctx, int delete) + struct xfrm_sec_ctx *ctx, int delete, + int *err) { struct xfrm_policy *pol, *ret; struct hlist_head *chain; struct hlist_node *entry; + *err = 0; write_lock_bh(&xfrm_policy_lock); chain = policy_hash_bysel(sel, sel->family, dir); ret = NULL; @@ -750,6 +752,11 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, xfrm_sec_ctx_match(ctx, pol->security)) { xfrm_pol_hold(pol); if (delete) { + *err = security_xfrm_policy_delete(pol); + if (*err) { + write_unlock_bh(&xfrm_policy_lock); + return pol; + } hlist_del(&pol->bydst); hlist_del(&pol->byidx); xfrm_policy_count[dir]--; @@ -768,12 +775,14 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, } EXPORT_SYMBOL(xfrm_policy_bysel_ctx); -struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete) +struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, + int *err) { struct xfrm_policy *pol, *ret; struct hlist_head *chain; struct hlist_node *entry; + *err = 0; write_lock_bh(&xfrm_policy_lock); chain = xfrm_policy_byidx + idx_hash(id); ret = NULL; @@ -781,6 +790,11 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete) if (pol->type == type && pol->index == id) { xfrm_pol_hold(pol); if (delete) { + *err = security_xfrm_policy_delete(pol); + if (*err) { + write_unlock_bh(&xfrm_policy_lock); + return pol; + } hlist_del(&pol->bydst); hlist_del(&pol->byidx); xfrm_policy_count[dir]--; @@ -1024,17 +1038,17 @@ end: static inline int policy_to_flow_dir(int dir) { if (XFRM_POLICY_IN == FLOW_DIR_IN && - XFRM_POLICY_OUT == FLOW_DIR_OUT && - XFRM_POLICY_FWD == FLOW_DIR_FWD) - return dir; - switch (dir) { - default: - case XFRM_POLICY_IN: - return FLOW_DIR_IN; - case XFRM_POLICY_OUT: - return FLOW_DIR_OUT; - case XFRM_POLICY_FWD: - return FLOW_DIR_FWD; + XFRM_POLICY_OUT == FLOW_DIR_OUT && + XFRM_POLICY_FWD == FLOW_DIR_FWD) + return dir; + switch (dir) { + default: + case XFRM_POLICY_IN: + return FLOW_DIR_IN; + case XFRM_POLICY_OUT: + return FLOW_DIR_OUT; + case XFRM_POLICY_FWD: + return FLOW_DIR_FWD; }; } @@ -1044,9 +1058,9 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc read_lock_bh(&xfrm_policy_lock); if ((pol = sk->sk_policy[dir]) != NULL) { - int match = xfrm_selector_match(&pol->selector, fl, + int match = xfrm_selector_match(&pol->selector, fl, sk->sk_family); - int err = 0; + int err = 0; if (match) { err = security_xfrm_policy_lookup(pol, fl->secid, @@ -1511,7 +1525,7 @@ restart: } *dst_p = dst; dst_release(dst_orig); - xfrm_pols_put(pols, npols); + xfrm_pols_put(pols, npols); return 0; error: @@ -1546,11 +1560,11 @@ xfrm_secpath_reject(int idx, struct sk_buff *skb, struct flowi *fl) */ static inline int -xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x, +xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x, unsigned short family) { if (xfrm_state_kern(x)) - return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, family); + return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, tmpl->encap_family); return x->id.proto == tmpl->id.proto && (x->id.spi == tmpl->id.spi || !tmpl->id.spi) && (x->props.reqid == tmpl->reqid || !tmpl->reqid) && @@ -1619,7 +1633,7 @@ static inline int secpath_has_nontransport(struct sec_path *sp, int k, int *idxp return 0; } -int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, +int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) { struct xfrm_policy *pol; @@ -1997,9 +2011,14 @@ void xfrm_audit_log(uid_t auid, u32 sid, int type, int result, if (audit_enabled == 0) return; + BUG_ON((type == AUDIT_MAC_IPSEC_ADDSA || + type == AUDIT_MAC_IPSEC_DELSA) && !x); + BUG_ON((type == AUDIT_MAC_IPSEC_ADDSPD || + type == AUDIT_MAC_IPSEC_DELSPD) && !xp); + audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type); if (audit_buf == NULL) - return; + return; switch(type) { case AUDIT_MAC_IPSEC_ADDSA: @@ -2243,7 +2262,7 @@ static int xfrm_migrate_selector_match(struct xfrm_selector *sel_cmp, if (sel_cmp->proto == IPSEC_ULPROTO_ANY) { if (sel_tgt->family == sel_cmp->family && xfrm_addr_cmp(&sel_tgt->daddr, &sel_cmp->daddr, - sel_cmp->family) == 0 && + sel_cmp->family) == 0 && xfrm_addr_cmp(&sel_tgt->saddr, &sel_cmp->saddr, sel_cmp->family) == 0 && sel_tgt->prefixlen_d == sel_cmp->prefixlen_d &&