ipsec-2023-08-15
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH7ZpcWbFyOOp6OJbrB3Eaf9PW7cFAmTbRoQACgkQrB3Eaf9P W7eY+A/8DJtqwFs1uAahS9jCX1bxf3vKKUPkEKu3IfcZVv2WcMVDI7XRLnBb93PC GR1RQskCErXMrVv7mmaBuk/uZAcAFQUkzna3MmyAw4lFfJSWORD6rzGiFeDVMsvx 7gczhYC6aPwhiyAqk6eoNTKxLaZ0zfGiW9ZKWdZXuTjp+ijksa56gEdKsPwMQIht FE4+CHia0dxFK0bUZMLHc4ixQbqKkHj/qVxB8k8zQnDgmCavjlEAnc+PAOX+SNxm uju4gDV/9qXYOkHTwRD9/aPcvCofTlD9XynSHkMC24yLS6Ir4A1mFUZywNSiwcgX //WxymD1N93inuHGzVluhm6Jy+4hTaS5p1y+H86L2TfC9b5SOrNYtj3yLB3aqDgq 1+4t4cVAtpk7uLfPYKzreDJH+CoxQDC8x+0dlzQUGnV11eIJ2RA0brJhFqHjOlbD SAQtBwkPqlAXnrdDr2pUhyrlrwAGXux8T5u5tF3NSS3FEwh7akRBfU2HV6vPEE80 qPIxHSbA9d0j+tOjbkHIYEv9fMHHFC/aFLZMYOew016TKGBJth4g+DJqJiEEDZZh iEIC62lrMV2qsyW5PdYdxGesZaAC/4koFCTBgkBYyIC/4gm5E74Ygu5B2A3xx89p H6MlF3Miofsf9aSh1vw4cyb69mPaP1XG95OGTqc0qpV2XhhjpE0= =UVTC -----END PGP SIGNATURE----- Merge tag 'ipsec-2023-08-15' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec Steffen Klassert says: ==================== 1) Fix a slab-out-of-bounds read in xfrm_address_filter. From Lin Ma. 2) Fix the pfkey sadb_x_filter validation. From Lin Ma. 3) Use the correct nla_policy structure for XFRMA_SEC_CTX. From Lin Ma. 4) Fix warnings triggerable by bad packets in the encap functions. From Herbert Xu. 5) Fix some slab-use-after-free in decode_session6. From Zhengchao Shao. 6) Fix a possible NULL piointer dereference in xfrm_update_ae_params. Lin Ma. 7) Add a forgotten nla_policy for XFRMA_MTIMER_THRESH. From Lin Ma. 8) Don't leak offloaded policies. From Leon Romanovsky. 9) Delete also the offloading part of an acquire state. From Leon Romanovsky. Please pull or let me know if there are problems.
This commit is contained in:
commit
5fc43ce03b
|
@ -1984,6 +1984,7 @@ static inline void xfrm_dev_state_free(struct xfrm_state *x)
|
|||
if (dev->xfrmdev_ops->xdo_dev_state_free)
|
||||
dev->xfrmdev_ops->xdo_dev_state_free(x);
|
||||
xso->dev = NULL;
|
||||
xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
|
||||
netdev_put(dev, &xso->dev_tracker);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -287,12 +287,12 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
switch (skb->protocol) {
|
||||
case htons(ETH_P_IP):
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
break;
|
||||
default:
|
||||
goto tx_err;
|
||||
|
|
|
@ -568,12 +568,12 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
vti6_addr_conflict(t, ipv6_hdr(skb)))
|
||||
goto tx_err;
|
||||
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
break;
|
||||
case htons(ETH_P_IP):
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
break;
|
||||
default:
|
||||
goto tx_err;
|
||||
|
|
|
@ -1848,9 +1848,9 @@ static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_ms
|
|||
if (ext_hdrs[SADB_X_EXT_FILTER - 1]) {
|
||||
struct sadb_x_filter *xfilter = ext_hdrs[SADB_X_EXT_FILTER - 1];
|
||||
|
||||
if ((xfilter->sadb_x_filter_splen >=
|
||||
if ((xfilter->sadb_x_filter_splen >
|
||||
(sizeof(xfrm_address_t) << 3)) ||
|
||||
(xfilter->sadb_x_filter_dplen >=
|
||||
(xfilter->sadb_x_filter_dplen >
|
||||
(sizeof(xfrm_address_t) << 3))) {
|
||||
mutex_unlock(&pfk->dump_lock);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -108,7 +108,7 @@ static const struct nla_policy compat_policy[XFRMA_MAX+1] = {
|
|||
[XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) },
|
||||
[XFRMA_ENCAP] = { .len = sizeof(struct xfrm_encap_tmpl) },
|
||||
[XFRMA_TMPL] = { .len = sizeof(struct xfrm_user_tmpl) },
|
||||
[XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_sec_ctx) },
|
||||
[XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_user_sec_ctx) },
|
||||
[XFRMA_LTIME_VAL] = { .len = sizeof(struct xfrm_lifetime_cur) },
|
||||
[XFRMA_REPLAY_VAL] = { .len = sizeof(struct xfrm_replay_state) },
|
||||
[XFRMA_REPLAY_THRESH] = { .type = NLA_U32 },
|
||||
|
|
|
@ -180,6 +180,8 @@ static int xfrm4_remove_beet_encap(struct xfrm_state *x, struct sk_buff *skb)
|
|||
int optlen = 0;
|
||||
int err = -EINVAL;
|
||||
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
|
||||
if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) {
|
||||
struct ip_beet_phdr *ph;
|
||||
int phlen;
|
||||
|
@ -232,6 +234,8 @@ static int xfrm4_remove_tunnel_encap(struct xfrm_state *x, struct sk_buff *skb)
|
|||
{
|
||||
int err = -EINVAL;
|
||||
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
|
||||
goto out;
|
||||
|
||||
|
@ -267,6 +271,8 @@ static int xfrm6_remove_tunnel_encap(struct xfrm_state *x, struct sk_buff *skb)
|
|||
{
|
||||
int err = -EINVAL;
|
||||
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
|
||||
goto out;
|
||||
|
||||
|
@ -296,6 +302,8 @@ static int xfrm6_remove_beet_encap(struct xfrm_state *x, struct sk_buff *skb)
|
|||
int size = sizeof(struct ipv6hdr);
|
||||
int err;
|
||||
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
|
||||
err = skb_cow_head(skb, size + skb->mac_len);
|
||||
if (err)
|
||||
goto out;
|
||||
|
@ -346,6 +354,7 @@ xfrm_inner_mode_encap_remove(struct xfrm_state *x,
|
|||
return xfrm6_remove_tunnel_encap(x, skb);
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(1);
|
||||
|
@ -366,19 +375,6 @@ static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
|
|||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
switch (XFRM_MODE_SKB_CB(skb)->protocol) {
|
||||
case IPPROTO_IPIP:
|
||||
case IPPROTO_BEETPH:
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
break;
|
||||
case IPPROTO_IPV6:
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
break;
|
||||
}
|
||||
|
||||
return xfrm_inner_mode_encap_remove(x, skb);
|
||||
}
|
||||
|
||||
|
|
|
@ -537,8 +537,8 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
switch (skb->protocol) {
|
||||
case htons(ETH_P_IPV6):
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET6);
|
||||
if (!dst) {
|
||||
fl.u.ip6.flowi6_oif = dev->ifindex;
|
||||
fl.u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
|
||||
|
@ -552,8 +552,8 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
break;
|
||||
case htons(ETH_P_IP):
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
|
||||
xfrm_decode_session(skb, &fl, AF_INET);
|
||||
if (!dst) {
|
||||
struct rtable *rt;
|
||||
|
||||
|
|
|
@ -1324,12 +1324,8 @@ found:
|
|||
struct xfrm_dev_offload *xso = &x->xso;
|
||||
|
||||
if (xso->type == XFRM_DEV_OFFLOAD_PACKET) {
|
||||
xso->dev->xfrmdev_ops->xdo_dev_state_delete(x);
|
||||
xso->dir = 0;
|
||||
netdev_put(xso->dev, &xso->dev_tracker);
|
||||
xso->dev = NULL;
|
||||
xso->real_dev = NULL;
|
||||
xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
|
||||
xfrm_dev_state_delete(x);
|
||||
xfrm_dev_state_free(x);
|
||||
}
|
||||
#endif
|
||||
x->km.state = XFRM_STATE_DEAD;
|
||||
|
|
|
@ -628,7 +628,7 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs,
|
|||
struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
|
||||
struct nlattr *mt = attrs[XFRMA_MTIMER_THRESH];
|
||||
|
||||
if (re) {
|
||||
if (re && x->replay_esn && x->preplay_esn) {
|
||||
struct xfrm_replay_state_esn *replay_esn;
|
||||
replay_esn = nla_data(re);
|
||||
memcpy(x->replay_esn, replay_esn,
|
||||
|
@ -1267,6 +1267,15 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
sizeof(*filter), GFP_KERNEL);
|
||||
if (filter == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/* see addr_match(), (prefix length >> 5) << 2
|
||||
* will be used to compare xfrm_address_t
|
||||
*/
|
||||
if (filter->splen > (sizeof(xfrm_address_t) << 3) ||
|
||||
filter->dplen > (sizeof(xfrm_address_t) << 3)) {
|
||||
kfree(filter);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (attrs[XFRMA_PROTO])
|
||||
|
@ -2336,6 +2345,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
NETLINK_CB(skb).portid);
|
||||
}
|
||||
} else {
|
||||
xfrm_dev_policy_delete(xp);
|
||||
xfrm_audit_policy_delete(xp, err ? 0 : 1, true);
|
||||
|
||||
if (err != 0)
|
||||
|
@ -3015,7 +3025,7 @@ const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
|
|||
[XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) },
|
||||
[XFRMA_ENCAP] = { .len = sizeof(struct xfrm_encap_tmpl) },
|
||||
[XFRMA_TMPL] = { .len = sizeof(struct xfrm_user_tmpl) },
|
||||
[XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_sec_ctx) },
|
||||
[XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_user_sec_ctx) },
|
||||
[XFRMA_LTIME_VAL] = { .len = sizeof(struct xfrm_lifetime_cur) },
|
||||
[XFRMA_REPLAY_VAL] = { .len = sizeof(struct xfrm_replay_state) },
|
||||
[XFRMA_REPLAY_THRESH] = { .type = NLA_U32 },
|
||||
|
@ -3035,6 +3045,7 @@ const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
|
|||
[XFRMA_SET_MARK] = { .type = NLA_U32 },
|
||||
[XFRMA_SET_MARK_MASK] = { .type = NLA_U32 },
|
||||
[XFRMA_IF_ID] = { .type = NLA_U32 },
|
||||
[XFRMA_MTIMER_THRESH] = { .type = NLA_U32 },
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(xfrma_policy);
|
||||
|
||||
|
|
Loading…
Reference in New Issue