.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* xfrm_user.c: User interface to configure xfrm engine. |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2002 David S. Miller (davem@redhat.com) |
---|
.. | .. |
---|
521 | 522 | struct nlattr *et = attrs[XFRMA_ETIMER_THRESH]; |
---|
522 | 523 | struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH]; |
---|
523 | 524 | |
---|
524 | | - if (re) { |
---|
| 525 | + if (re && x->replay_esn && x->preplay_esn) { |
---|
525 | 526 | struct xfrm_replay_state_esn *replay_esn; |
---|
526 | 527 | replay_esn = nla_data(re); |
---|
527 | 528 | memcpy(x->replay_esn, replay_esn, |
---|
.. | .. |
---|
620 | 621 | |
---|
621 | 622 | xfrm_smark_init(attrs, &x->props.smark); |
---|
622 | 623 | |
---|
623 | | - if (attrs[XFRMA_IF_ID]) { |
---|
| 624 | + if (attrs[XFRMA_IF_ID]) |
---|
624 | 625 | x->if_id = nla_get_u32(attrs[XFRMA_IF_ID]); |
---|
625 | | - if (!x->if_id) { |
---|
626 | | - err = -EINVAL; |
---|
627 | | - goto error; |
---|
628 | | - } |
---|
629 | | - } |
---|
630 | 626 | |
---|
631 | 627 | err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV]); |
---|
632 | 628 | if (err) |
---|
.. | .. |
---|
1043 | 1039 | u8 proto = 0; |
---|
1044 | 1040 | int err; |
---|
1045 | 1041 | |
---|
1046 | | - err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX, xfrma_policy, |
---|
1047 | | - NULL); |
---|
| 1042 | + err = nlmsg_parse_deprecated(cb->nlh, 0, attrs, XFRMA_MAX, |
---|
| 1043 | + xfrma_policy, cb->extack); |
---|
1048 | 1044 | if (err < 0) |
---|
1049 | 1045 | return err; |
---|
1050 | 1046 | |
---|
.. | .. |
---|
1053 | 1049 | sizeof(*filter), GFP_KERNEL); |
---|
1054 | 1050 | if (filter == NULL) |
---|
1055 | 1051 | return -ENOMEM; |
---|
| 1052 | + |
---|
| 1053 | + /* see addr_match(), (prefix length >> 5) << 2 |
---|
| 1054 | + * will be used to compare xfrm_address_t |
---|
| 1055 | + */ |
---|
| 1056 | + if (filter->splen > (sizeof(xfrm_address_t) << 3) || |
---|
| 1057 | + filter->dplen > (sizeof(xfrm_address_t) << 3)) { |
---|
| 1058 | + kfree(filter); |
---|
| 1059 | + return -EINVAL; |
---|
| 1060 | + } |
---|
1056 | 1061 | } |
---|
1057 | 1062 | |
---|
1058 | 1063 | if (attrs[XFRMA_PROTO]) |
---|
.. | .. |
---|
1357 | 1362 | |
---|
1358 | 1363 | mark = xfrm_mark_get(attrs, &m); |
---|
1359 | 1364 | |
---|
1360 | | - if (attrs[XFRMA_IF_ID]) { |
---|
| 1365 | + if (attrs[XFRMA_IF_ID]) |
---|
1361 | 1366 | if_id = nla_get_u32(attrs[XFRMA_IF_ID]); |
---|
1362 | | - if (!if_id) { |
---|
1363 | | - err = -EINVAL; |
---|
1364 | | - goto out_noput; |
---|
1365 | | - } |
---|
1366 | | - } |
---|
1367 | 1367 | |
---|
1368 | 1368 | if (p->info.seq) { |
---|
1369 | 1369 | x = xfrm_find_acq_byseq(net, mark, p->info.seq); |
---|
.. | .. |
---|
1676 | 1676 | |
---|
1677 | 1677 | xfrm_mark_get(attrs, &xp->mark); |
---|
1678 | 1678 | |
---|
1679 | | - if (attrs[XFRMA_IF_ID]) { |
---|
| 1679 | + if (attrs[XFRMA_IF_ID]) |
---|
1680 | 1680 | xp->if_id = nla_get_u32(attrs[XFRMA_IF_ID]); |
---|
1681 | | - if (!xp->if_id) { |
---|
1682 | | - err = -EINVAL; |
---|
1683 | | - goto error; |
---|
1684 | | - } |
---|
1685 | | - } |
---|
1686 | 1681 | |
---|
1687 | 1682 | return xp; |
---|
1688 | 1683 | error: |
---|
.. | .. |
---|
1926 | 1921 | struct km_event c; |
---|
1927 | 1922 | int delete; |
---|
1928 | 1923 | struct xfrm_mark m; |
---|
1929 | | - u32 mark = xfrm_mark_get(attrs, &m); |
---|
1930 | 1924 | u32 if_id = 0; |
---|
1931 | 1925 | |
---|
1932 | 1926 | p = nlmsg_data(nlh); |
---|
.. | .. |
---|
1943 | 1937 | if (attrs[XFRMA_IF_ID]) |
---|
1944 | 1938 | if_id = nla_get_u32(attrs[XFRMA_IF_ID]); |
---|
1945 | 1939 | |
---|
| 1940 | + xfrm_mark_get(attrs, &m); |
---|
| 1941 | + |
---|
1946 | 1942 | if (p->index) |
---|
1947 | | - xp = xfrm_policy_byid(net, mark, if_id, type, p->dir, p->index, delete, &err); |
---|
| 1943 | + xp = xfrm_policy_byid(net, &m, if_id, type, p->dir, |
---|
| 1944 | + p->index, delete, &err); |
---|
1948 | 1945 | else { |
---|
1949 | 1946 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
---|
1950 | 1947 | struct xfrm_sec_ctx *ctx; |
---|
.. | .. |
---|
1961 | 1958 | if (err) |
---|
1962 | 1959 | return err; |
---|
1963 | 1960 | } |
---|
1964 | | - xp = xfrm_policy_bysel_ctx(net, mark, if_id, type, p->dir, &p->sel, |
---|
1965 | | - ctx, delete, &err); |
---|
| 1961 | + xp = xfrm_policy_bysel_ctx(net, &m, if_id, type, p->dir, |
---|
| 1962 | + &p->sel, ctx, delete, &err); |
---|
1966 | 1963 | security_xfrm_policy_free(ctx); |
---|
1967 | 1964 | } |
---|
1968 | 1965 | if (xp == NULL) |
---|
.. | .. |
---|
2229 | 2226 | u8 type = XFRM_POLICY_TYPE_MAIN; |
---|
2230 | 2227 | int err = -ENOENT; |
---|
2231 | 2228 | struct xfrm_mark m; |
---|
2232 | | - u32 mark = xfrm_mark_get(attrs, &m); |
---|
2233 | 2229 | u32 if_id = 0; |
---|
2234 | 2230 | |
---|
2235 | 2231 | err = copy_from_user_policy_type(&type, attrs); |
---|
.. | .. |
---|
2243 | 2239 | if (attrs[XFRMA_IF_ID]) |
---|
2244 | 2240 | if_id = nla_get_u32(attrs[XFRMA_IF_ID]); |
---|
2245 | 2241 | |
---|
| 2242 | + xfrm_mark_get(attrs, &m); |
---|
| 2243 | + |
---|
2246 | 2244 | if (p->index) |
---|
2247 | | - xp = xfrm_policy_byid(net, mark, if_id, type, p->dir, p->index, 0, &err); |
---|
| 2245 | + xp = xfrm_policy_byid(net, &m, if_id, type, p->dir, p->index, |
---|
| 2246 | + 0, &err); |
---|
2248 | 2247 | else { |
---|
2249 | 2248 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
---|
2250 | 2249 | struct xfrm_sec_ctx *ctx; |
---|
.. | .. |
---|
2261 | 2260 | if (err) |
---|
2262 | 2261 | return err; |
---|
2263 | 2262 | } |
---|
2264 | | - xp = xfrm_policy_bysel_ctx(net, mark, if_id, type, p->dir, |
---|
| 2263 | + xp = xfrm_policy_bysel_ctx(net, &m, if_id, type, p->dir, |
---|
2265 | 2264 | &p->sel, ctx, 0, &err); |
---|
2266 | 2265 | security_xfrm_policy_free(ctx); |
---|
2267 | 2266 | } |
---|
.. | .. |
---|
2433 | 2432 | int n = 0; |
---|
2434 | 2433 | struct net *net = sock_net(skb->sk); |
---|
2435 | 2434 | struct xfrm_encap_tmpl *encap = NULL; |
---|
| 2435 | + u32 if_id = 0; |
---|
2436 | 2436 | |
---|
2437 | 2437 | if (attrs[XFRMA_MIGRATE] == NULL) |
---|
2438 | 2438 | return -EINVAL; |
---|
.. | .. |
---|
2457 | 2457 | return 0; |
---|
2458 | 2458 | } |
---|
2459 | 2459 | |
---|
2460 | | - err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap); |
---|
| 2460 | + if (attrs[XFRMA_IF_ID]) |
---|
| 2461 | + if_id = nla_get_u32(attrs[XFRMA_IF_ID]); |
---|
| 2462 | + |
---|
| 2463 | + err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap, if_id); |
---|
2461 | 2464 | |
---|
2462 | 2465 | kfree(encap); |
---|
2463 | 2466 | |
---|
.. | .. |
---|
2630 | 2633 | [XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) }, |
---|
2631 | 2634 | [XFRMA_ENCAP] = { .len = sizeof(struct xfrm_encap_tmpl) }, |
---|
2632 | 2635 | [XFRMA_TMPL] = { .len = sizeof(struct xfrm_user_tmpl) }, |
---|
2633 | | - [XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_sec_ctx) }, |
---|
| 2636 | + [XFRMA_SEC_CTX] = { .len = sizeof(struct xfrm_user_sec_ctx) }, |
---|
2634 | 2637 | [XFRMA_LTIME_VAL] = { .len = sizeof(struct xfrm_lifetime_cur) }, |
---|
2635 | 2638 | [XFRMA_REPLAY_VAL] = { .len = sizeof(struct xfrm_replay_state) }, |
---|
2636 | 2639 | [XFRMA_REPLAY_THRESH] = { .type = NLA_U32 }, |
---|
.. | .. |
---|
2751 | 2754 | goto err; |
---|
2752 | 2755 | } |
---|
2753 | 2756 | |
---|
2754 | | - err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, |
---|
2755 | | - link->nla_max ? : XFRMA_MAX, |
---|
2756 | | - link->nla_pol ? : xfrma_policy, extack); |
---|
| 2757 | + err = nlmsg_parse_deprecated(nlh, xfrm_msg_min[type], attrs, |
---|
| 2758 | + link->nla_max ? : XFRMA_MAX, |
---|
| 2759 | + link->nla_pol ? : xfrma_policy, extack); |
---|
2757 | 2760 | if (err < 0) |
---|
2758 | 2761 | goto err; |
---|
2759 | 2762 | |
---|
.. | .. |
---|
2764 | 2767 | |
---|
2765 | 2768 | err = link->doit(skb, nlh, attrs); |
---|
2766 | 2769 | |
---|
| 2770 | + /* We need to free skb allocated in xfrm_alloc_compat() before |
---|
| 2771 | + * returning from this function, because consume_skb() won't take |
---|
| 2772 | + * care of frag_list since netlink destructor sets |
---|
| 2773 | + * sbk->head to NULL. (see netlink_skb_destructor()) |
---|
| 2774 | + */ |
---|
| 2775 | + if (skb_has_frag_list(skb)) { |
---|
| 2776 | + kfree_skb(skb_shinfo(skb)->frag_list); |
---|
| 2777 | + skb_shinfo(skb)->frag_list = NULL; |
---|
| 2778 | + } |
---|
| 2779 | + |
---|
2767 | 2780 | err: |
---|
2768 | 2781 | kvfree(nlh64); |
---|
2769 | 2782 | return err; |
---|