Commit eee8abe5 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [BRIDGE]: adding new device to bridge should enable if up
  [IPV6]: Do not set IF_READY if device is down
  [IPSEC]: xfrm audit hook misplaced in pfkey_delete and xfrm_del_sa
  [IPSEC]: Add xfrm policy change auditing to pfkey_spdget
  [IPSEC]: xfrm_policy delete security check misplaced
  [CONNECTOR]: Bugfix for cn_call_callback()
  [DCCP]: Revert patch which disables bidirectional mode
  [IPV6]: Handle np->opt being NULL in ipv6_getsockopt_sticky().
  [UDP]: Reread uh pointer after pskb_trim
  [NETFILTER]: nfnetlink_log: fix crash on bridged packet
  [NETFILTER]: nfnetlink_log: zero-terminate prefix
  [NETFILTER]: nf_conntrack_ipv6: fix incorrect classification of IPv6 fragments as ESTABLISHED
parents 06aa5b4a de79059e
...@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(cn_netlink_send); ...@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
*/ */
static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data) static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data)
{ {
struct cn_callback_entry *__cbq; struct cn_callback_entry *__cbq, *__new_cbq;
struct cn_dev *dev = &cdev; struct cn_dev *dev = &cdev;
int err = -ENODEV; int err = -ENODEV;
...@@ -148,27 +148,27 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v ...@@ -148,27 +148,27 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
} else { } else {
struct cn_callback_data *d; struct cn_callback_data *d;
__cbq = kzalloc(sizeof(*__cbq), GFP_ATOMIC); err = -ENOMEM;
if (__cbq) { __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
d = &__cbq->data; if (__new_cbq) {
d = &__new_cbq->data;
d->callback_priv = msg; d->callback_priv = msg;
d->callback = __cbq->data.callback; d->callback = __cbq->data.callback;
d->ddata = data; d->ddata = data;
d->destruct_data = destruct_data; d->destruct_data = destruct_data;
d->free = __cbq; d->free = __new_cbq;
INIT_WORK(&__cbq->work, INIT_WORK(&__new_cbq->work,
&cn_queue_wrapper); &cn_queue_wrapper);
if (queue_work(dev->cbdev->cn_queue, if (queue_work(dev->cbdev->cn_queue,
&__cbq->work)) &__new_cbq->work))
err = 0; err = 0;
else { else {
kfree(__cbq); kfree(__new_cbq);
err = -EINVAL; err = -EINVAL;
} }
} else }
err = -ENOMEM;
} }
break; break;
} }
......
...@@ -988,8 +988,9 @@ extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, ...@@ -988,8 +988,9 @@ extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int,
int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
struct xfrm_selector *sel, struct xfrm_selector *sel,
struct xfrm_sec_ctx *ctx, int delete); struct xfrm_sec_ctx *ctx, int delete,
struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete); int *err);
struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
u32 xfrm_get_acqseq(void); u32 xfrm_get_acqseq(void);
void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi);
......
...@@ -428,6 +428,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) ...@@ -428,6 +428,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);
br_stp_recalculate_bridge_id(br); br_stp_recalculate_bridge_id(br);
br_features_recompute(br); br_features_recompute(br);
if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
(br->dev->flags & IFF_UP))
br_stp_enable_port(p);
spin_unlock_bh(&br->lock); spin_unlock_bh(&br->lock);
dev_set_mtu(br->dev, br_min_mtu(br)); dev_set_mtu(br->dev, br_min_mtu(br));
......
...@@ -545,12 +545,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) ...@@ -545,12 +545,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
/* set idle flag */ /* set idle flag */
hctx->ccid3hctx_idle = 1; hctx->ccid3hctx_idle = 1;
break; break;
case TFRC_SSTATE_NO_SENT: case TFRC_SSTATE_NO_SENT: /* fall through */
/*
* XXX when implementing bidirectional rx/tx check this again
*/
DCCP_WARN("Illegal ACK received - no packet sent\n");
/* fall through */
case TFRC_SSTATE_TERM: /* ignore feedback when closing */ case TFRC_SSTATE_TERM: /* ignore feedback when closing */
break; break;
} }
......
...@@ -248,18 +248,8 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, ...@@ -248,18 +248,8 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
DCCP_ACKVEC_STATE_RECEIVED)) DCCP_ACKVEC_STATE_RECEIVED))
goto discard; goto discard;
/*
* Deliver to the CCID module in charge.
* FIXME: Currently DCCP operates one-directional only, i.e. a listening
* server is not at the same time a connecting client. There is
* not much sense in delivering to both rx/tx sides at the moment
* (only one is active at a time); when moving to bidirectional
* service, this needs to be revised.
*/
if (dccp_sk(sk)->dccps_role == DCCP_ROLE_CLIENT)
ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
else /* listening or connected server */
ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
return __dccp_rcv_established(sk, skb, dh, len); return __dccp_rcv_established(sk, skb, dh, len);
discard: discard:
...@@ -494,11 +484,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, ...@@ -494,11 +484,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
DCCP_ACKVEC_STATE_RECEIVED)) DCCP_ACKVEC_STATE_RECEIVED))
goto discard; goto discard;
/* XXX see the comments in dccp_rcv_established about this */
if (dccp_sk(sk)->dccps_role == DCCP_ROLE_CLIENT)
ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
else
ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
} }
/* /*
......
...@@ -1215,6 +1215,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], ...@@ -1215,6 +1215,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen)) if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
goto short_packet; goto short_packet;
uh = skb->h.uh;
udp4_csum_init(skb, uh); udp4_csum_init(skb, uh);
......
...@@ -342,10 +342,6 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) ...@@ -342,10 +342,6 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
} }
#endif #endif
if (netif_carrier_ok(dev))
ndev->if_flags |= IF_READY;
ipv6_mc_init_dev(ndev); ipv6_mc_init_dev(ndev);
ndev->tstamp = jiffies; ndev->tstamp = jiffies;
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
......
...@@ -795,11 +795,15 @@ int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, ...@@ -795,11 +795,15 @@ int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
EXPORT_SYMBOL(compat_ipv6_setsockopt); EXPORT_SYMBOL(compat_ipv6_setsockopt);
#endif #endif
static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr, static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
char __user *optval, int len) char __user *optval, int len)
{ {
if (!hdr) struct ipv6_opt_hdr *hdr;
if (!opt || !opt->hopopt)
return 0; return 0;
hdr = opt->hopopt;
len = min_t(int, len, ipv6_optlen(hdr)); len = min_t(int, len, ipv6_optlen(hdr));
if (copy_to_user(optval, hdr, ipv6_optlen(hdr))) if (copy_to_user(optval, hdr, ipv6_optlen(hdr)))
return -EFAULT; return -EFAULT;
...@@ -940,7 +944,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, ...@@ -940,7 +944,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
{ {
lock_sock(sk); lock_sock(sk);
len = ipv6_getsockopt_sticky(sk, np->opt->hopopt, len = ipv6_getsockopt_sticky(sk, np->opt,
optval, len); optval, len);
release_sock(sk); release_sock(sk);
return put_user(len, optlen); return put_user(len, optlen);
......
...@@ -257,6 +257,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum, ...@@ -257,6 +257,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
} }
nf_conntrack_get(reasm->nfct); nf_conntrack_get(reasm->nfct);
(*pskb)->nfct = reasm->nfct; (*pskb)->nfct = reasm->nfct;
(*pskb)->nfctinfo = reasm->nfctinfo;
return NF_ACCEPT; return NF_ACCEPT;
} }
......
...@@ -1467,9 +1467,6 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h ...@@ -1467,9 +1467,6 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
err = xfrm_state_delete(x); err = xfrm_state_delete(x);
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
if (err < 0) if (err < 0)
goto out; goto out;
...@@ -1478,6 +1475,8 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h ...@@ -1478,6 +1475,8 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
c.event = XFRM_MSG_DELSA; c.event = XFRM_MSG_DELSA;
km_state_notify(x, &c); km_state_notify(x, &c);
out: out:
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
xfrm_state_put(x); xfrm_state_put(x);
return err; return err;
...@@ -2294,14 +2293,12 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg ...@@ -2294,14 +2293,12 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
} }
xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1, xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1,
&sel, tmp.security, 1); &sel, tmp.security, 1, &err);
security_xfrm_policy_free(&tmp); security_xfrm_policy_free(&tmp);
if (xp == NULL) if (xp == NULL)
return -ENOENT; return -ENOENT;
err = security_xfrm_policy_delete(xp);
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
...@@ -2539,7 +2536,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb, ...@@ -2539,7 +2536,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
{ {
unsigned int dir; unsigned int dir;
int err; int err = 0, delete;
struct sadb_x_policy *pol; struct sadb_x_policy *pol;
struct xfrm_policy *xp; struct xfrm_policy *xp;
struct km_event c; struct km_event c;
...@@ -2551,16 +2548,20 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h ...@@ -2551,16 +2548,20 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
if (dir >= XFRM_POLICY_MAX) if (dir >= XFRM_POLICY_MAX)
return -EINVAL; return -EINVAL;
delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2);
xp = xfrm_policy_byid(XFRM_POLICY_TYPE_MAIN, dir, pol->sadb_x_policy_id, xp = xfrm_policy_byid(XFRM_POLICY_TYPE_MAIN, dir, pol->sadb_x_policy_id,
hdr->sadb_msg_type == SADB_X_SPDDELETE2); delete, &err);
if (xp == NULL) if (xp == NULL)
return -ENOENT; return -ENOENT;
err = 0; if (delete) {
xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
if (err)
goto out;
c.seq = hdr->sadb_msg_seq; c.seq = hdr->sadb_msg_seq;
c.pid = hdr->sadb_msg_pid; c.pid = hdr->sadb_msg_pid;
if (hdr->sadb_msg_type == SADB_X_SPDDELETE2) {
c.data.byid = 1; c.data.byid = 1;
c.event = XFRM_MSG_DELPOLICY; c.event = XFRM_MSG_DELPOLICY;
km_policy_notify(xp, dir, &c); km_policy_notify(xp, dir, &c);
...@@ -2568,6 +2569,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h ...@@ -2568,6 +2569,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
err = key_pol_get_resp(sk, xp, hdr, dir); err = key_pol_get_resp(sk, xp, hdr, dir);
} }
out:
xfrm_pol_put(xp); xfrm_pol_put(xp);
return err; return err;
} }
......
...@@ -486,7 +486,7 @@ __build_packet_message(struct nfulnl_instance *inst, ...@@ -486,7 +486,7 @@ __build_packet_message(struct nfulnl_instance *inst,
* for physical device (when called from ipv4) */ * for physical device (when called from ipv4) */
NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV, NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV,
sizeof(tmp_uint), &tmp_uint); sizeof(tmp_uint), &tmp_uint);
if (skb->nf_bridge) { if (skb->nf_bridge && skb->nf_bridge->physoutdev) {
tmp_uint = tmp_uint =
htonl(skb->nf_bridge->physoutdev->ifindex); htonl(skb->nf_bridge->physoutdev->ifindex);
NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
...@@ -615,7 +615,7 @@ nfulnl_log_packet(unsigned int pf, ...@@ -615,7 +615,7 @@ nfulnl_log_packet(unsigned int pf,
plen = 0; plen = 0;
if (prefix) if (prefix)
plen = strlen(prefix); plen = strlen(prefix) + 1;
/* all macros expand to constant values at compile time */ /* all macros expand to constant values at compile time */
/* FIXME: do we want to make the size calculation conditional based on /* FIXME: do we want to make the size calculation conditional based on
......
...@@ -735,12 +735,14 @@ EXPORT_SYMBOL(xfrm_policy_insert); ...@@ -735,12 +735,14 @@ EXPORT_SYMBOL(xfrm_policy_insert);
struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
struct xfrm_selector *sel, 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 xfrm_policy *pol, *ret;
struct hlist_head *chain; struct hlist_head *chain;
struct hlist_node *entry; struct hlist_node *entry;
*err = 0;
write_lock_bh(&xfrm_policy_lock); write_lock_bh(&xfrm_policy_lock);
chain = policy_hash_bysel(sel, sel->family, dir); chain = policy_hash_bysel(sel, sel->family, dir);
ret = NULL; ret = NULL;
...@@ -750,6 +752,11 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, ...@@ -750,6 +752,11 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
xfrm_sec_ctx_match(ctx, pol->security)) { xfrm_sec_ctx_match(ctx, pol->security)) {
xfrm_pol_hold(pol); xfrm_pol_hold(pol);
if (delete) { 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->bydst);
hlist_del(&pol->byidx); hlist_del(&pol->byidx);
xfrm_policy_count[dir]--; xfrm_policy_count[dir]--;
...@@ -768,12 +775,14 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, ...@@ -768,12 +775,14 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
} }
EXPORT_SYMBOL(xfrm_policy_bysel_ctx); 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 xfrm_policy *pol, *ret;
struct hlist_head *chain; struct hlist_head *chain;
struct hlist_node *entry; struct hlist_node *entry;
*err = 0;
write_lock_bh(&xfrm_policy_lock); write_lock_bh(&xfrm_policy_lock);
chain = xfrm_policy_byidx + idx_hash(id); chain = xfrm_policy_byidx + idx_hash(id);
ret = NULL; ret = NULL;
...@@ -781,6 +790,11 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete) ...@@ -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) { if (pol->type == type && pol->index == id) {
xfrm_pol_hold(pol); xfrm_pol_hold(pol);
if (delete) { 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->bydst);
hlist_del(&pol->byidx); hlist_del(&pol->byidx);
xfrm_policy_count[dir]--; xfrm_policy_count[dir]--;
......
...@@ -530,9 +530,6 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -530,9 +530,6 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
err = xfrm_state_delete(x); err = xfrm_state_delete(x);
xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
if (err < 0) if (err < 0)
goto out; goto out;
...@@ -542,6 +539,8 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -542,6 +539,8 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
km_state_notify(x, &c); km_state_notify(x, &c);
out: out:
xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
xfrm_state_put(x); xfrm_state_put(x);
return err; return err;
} }
...@@ -1254,7 +1253,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -1254,7 +1253,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
return err; return err;
if (p->index) if (p->index)
xp = xfrm_policy_byid(type, p->dir, p->index, delete); xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err);
else { else {
struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
struct xfrm_policy tmp; struct xfrm_policy tmp;
...@@ -1270,7 +1269,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -1270,7 +1269,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
if ((err = security_xfrm_policy_alloc(&tmp, uctx))) if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
return err; return err;
} }
xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete); xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security,
delete, &err);
security_xfrm_policy_free(&tmp); security_xfrm_policy_free(&tmp);
} }
if (xp == NULL) if (xp == NULL)
...@@ -1288,8 +1288,6 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -1288,8 +1288,6 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
MSG_DONTWAIT); MSG_DONTWAIT);
} }
} else { } else {
err = security_xfrm_policy_delete(xp);
xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
...@@ -1303,9 +1301,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -1303,9 +1301,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
km_policy_notify(xp, p->dir, &c); km_policy_notify(xp, p->dir, &c);
} }
xfrm_pol_put(xp);
out: out:
xfrm_pol_put(xp);
return err; return err;
} }
...@@ -1502,7 +1499,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -1502,7 +1499,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
return err; return err;
if (p->index) if (p->index)
xp = xfrm_policy_byid(type, p->dir, p->index, 0); xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err);
else { else {
struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
struct xfrm_policy tmp; struct xfrm_policy tmp;
...@@ -1518,12 +1515,13 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -1518,12 +1515,13 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
if ((err = security_xfrm_policy_alloc(&tmp, uctx))) if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
return err; return err;
} }
xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, 0); xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security,
0, &err);
security_xfrm_policy_free(&tmp); security_xfrm_policy_free(&tmp);
} }
if (xp == NULL) if (xp == NULL)
return err; return -ENOENT;
read_lock(&xp->lock); read_lock(&xp->lock);
if (xp->dead) { if (xp->dead) {
read_unlock(&xp->lock); read_unlock(&xp->lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment