| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * net/key/af_key.c An implementation of PF_KEYv2 sockets. |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or |
|---|
| 5 | | - * modify it under the terms of the GNU General Public License |
|---|
| 6 | | - * as published by the Free Software Foundation; either version |
|---|
| 7 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 8 | 4 | * |
|---|
| 9 | 5 | * Authors: Maxim Giryaev <gem@asplinux.ru> |
|---|
| 10 | 6 | * David S. Miller <davem@redhat.com> |
|---|
| .. | .. |
|---|
| 932 | 928 | pfkey_sockaddr_fill(&x->props.saddr, 0, |
|---|
| 933 | 929 | (struct sockaddr *) (addr + 1), |
|---|
| 934 | 930 | x->props.family); |
|---|
| 935 | | - if (!addr->sadb_address_prefixlen) |
|---|
| 936 | | - BUG(); |
|---|
| 931 | + BUG_ON(!addr->sadb_address_prefixlen); |
|---|
| 937 | 932 | |
|---|
| 938 | 933 | /* dst address */ |
|---|
| 939 | 934 | addr = skb_put(skb, sizeof(struct sadb_address) + sockaddr_size); |
|---|
| .. | .. |
|---|
| 948 | 943 | pfkey_sockaddr_fill(&x->id.daddr, 0, |
|---|
| 949 | 944 | (struct sockaddr *) (addr + 1), |
|---|
| 950 | 945 | x->props.family); |
|---|
| 951 | | - if (!addr->sadb_address_prefixlen) |
|---|
| 952 | | - BUG(); |
|---|
| 946 | + BUG_ON(!addr->sadb_address_prefixlen); |
|---|
| 953 | 947 | |
|---|
| 954 | 948 | if (!xfrm_addr_equal(&x->sel.saddr, &x->props.saddr, |
|---|
| 955 | 949 | x->props.family)) { |
|---|
| .. | .. |
|---|
| 1707 | 1701 | pfk->registered |= (1<<hdr->sadb_msg_satype); |
|---|
| 1708 | 1702 | } |
|---|
| 1709 | 1703 | |
|---|
| 1704 | + mutex_lock(&pfkey_mutex); |
|---|
| 1710 | 1705 | xfrm_probe_algs(); |
|---|
| 1711 | 1706 | |
|---|
| 1712 | | - supp_skb = compose_sadb_supported(hdr, GFP_KERNEL); |
|---|
| 1707 | + supp_skb = compose_sadb_supported(hdr, GFP_KERNEL | __GFP_ZERO); |
|---|
| 1708 | + mutex_unlock(&pfkey_mutex); |
|---|
| 1709 | + |
|---|
| 1713 | 1710 | if (!supp_skb) { |
|---|
| 1714 | 1711 | if (hdr->sadb_msg_satype != SADB_SATYPE_UNSPEC) |
|---|
| 1715 | 1712 | pfk->registered &= ~(1<<hdr->sadb_msg_satype); |
|---|
| .. | .. |
|---|
| 2019 | 2016 | |
|---|
| 2020 | 2017 | static inline int pfkey_xfrm_policy2sec_ctx_size(const struct xfrm_policy *xp) |
|---|
| 2021 | 2018 | { |
|---|
| 2022 | | - struct xfrm_sec_ctx *xfrm_ctx = xp->security; |
|---|
| 2019 | + struct xfrm_sec_ctx *xfrm_ctx = xp->security; |
|---|
| 2023 | 2020 | |
|---|
| 2024 | 2021 | if (xfrm_ctx) { |
|---|
| 2025 | 2022 | int len = sizeof(struct sadb_x_sec_ctx); |
|---|
| .. | .. |
|---|
| 2413 | 2410 | return err; |
|---|
| 2414 | 2411 | } |
|---|
| 2415 | 2412 | |
|---|
| 2416 | | - xp = xfrm_policy_bysel_ctx(net, DUMMY_MARK, 0, XFRM_POLICY_TYPE_MAIN, |
|---|
| 2413 | + xp = xfrm_policy_bysel_ctx(net, &dummy_mark, 0, XFRM_POLICY_TYPE_MAIN, |
|---|
| 2417 | 2414 | pol->sadb_x_policy_dir - 1, &sel, pol_ctx, |
|---|
| 2418 | 2415 | 1, &err); |
|---|
| 2419 | 2416 | security_xfrm_policy_free(pol_ctx); |
|---|
| .. | .. |
|---|
| 2633 | 2630 | } |
|---|
| 2634 | 2631 | |
|---|
| 2635 | 2632 | return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i, |
|---|
| 2636 | | - kma ? &k : NULL, net, NULL); |
|---|
| 2633 | + kma ? &k : NULL, net, NULL, 0); |
|---|
| 2637 | 2634 | |
|---|
| 2638 | 2635 | out: |
|---|
| 2639 | 2636 | return err; |
|---|
| .. | .. |
|---|
| 2664 | 2661 | return -EINVAL; |
|---|
| 2665 | 2662 | |
|---|
| 2666 | 2663 | delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2); |
|---|
| 2667 | | - xp = xfrm_policy_byid(net, DUMMY_MARK, 0, XFRM_POLICY_TYPE_MAIN, |
|---|
| 2664 | + xp = xfrm_policy_byid(net, &dummy_mark, 0, XFRM_POLICY_TYPE_MAIN, |
|---|
| 2668 | 2665 | dir, pol->sadb_x_policy_id, delete, &err); |
|---|
| 2669 | 2666 | if (xp == NULL) |
|---|
| 2670 | 2667 | return -ENOENT; |
|---|
| .. | .. |
|---|
| 2836 | 2833 | void *ext_hdrs[SADB_EXT_MAX]; |
|---|
| 2837 | 2834 | int err; |
|---|
| 2838 | 2835 | |
|---|
| 2836 | + /* Non-zero return value of pfkey_broadcast() does not always signal |
|---|
| 2837 | + * an error and even on an actual error we may still want to process |
|---|
| 2838 | + * the message so rather ignore the return value. |
|---|
| 2839 | + */ |
|---|
| 2839 | 2840 | pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, |
|---|
| 2840 | 2841 | BROADCAST_PROMISC_ONLY, NULL, sock_net(sk)); |
|---|
| 2841 | 2842 | |
|---|
| .. | .. |
|---|
| 2944 | 2945 | return sz + sizeof(struct sadb_prop); |
|---|
| 2945 | 2946 | } |
|---|
| 2946 | 2947 | |
|---|
| 2947 | | -static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) |
|---|
| 2948 | +static int dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) |
|---|
| 2948 | 2949 | { |
|---|
| 2949 | 2950 | struct sadb_prop *p; |
|---|
| 2951 | + int sz = 0; |
|---|
| 2950 | 2952 | int i; |
|---|
| 2951 | 2953 | |
|---|
| 2952 | 2954 | p = skb_put(skb, sizeof(struct sadb_prop)); |
|---|
| .. | .. |
|---|
| 2974 | 2976 | c->sadb_comb_soft_addtime = 20*60*60; |
|---|
| 2975 | 2977 | c->sadb_comb_hard_usetime = 8*60*60; |
|---|
| 2976 | 2978 | c->sadb_comb_soft_usetime = 7*60*60; |
|---|
| 2979 | + sz += sizeof(*c); |
|---|
| 2977 | 2980 | } |
|---|
| 2978 | 2981 | } |
|---|
| 2982 | + |
|---|
| 2983 | + return sz + sizeof(*p); |
|---|
| 2979 | 2984 | } |
|---|
| 2980 | 2985 | |
|---|
| 2981 | | -static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) |
|---|
| 2986 | +static int dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) |
|---|
| 2982 | 2987 | { |
|---|
| 2983 | 2988 | struct sadb_prop *p; |
|---|
| 2989 | + int sz = 0; |
|---|
| 2984 | 2990 | int i, k; |
|---|
| 2985 | 2991 | |
|---|
| 2986 | 2992 | p = skb_put(skb, sizeof(struct sadb_prop)); |
|---|
| .. | .. |
|---|
| 3022 | 3028 | c->sadb_comb_soft_addtime = 20*60*60; |
|---|
| 3023 | 3029 | c->sadb_comb_hard_usetime = 8*60*60; |
|---|
| 3024 | 3030 | c->sadb_comb_soft_usetime = 7*60*60; |
|---|
| 3031 | + sz += sizeof(*c); |
|---|
| 3025 | 3032 | } |
|---|
| 3026 | 3033 | } |
|---|
| 3034 | + |
|---|
| 3035 | + return sz + sizeof(*p); |
|---|
| 3027 | 3036 | } |
|---|
| 3028 | 3037 | |
|---|
| 3029 | 3038 | static int key_notify_policy_expire(struct xfrm_policy *xp, const struct km_event *c) |
|---|
| .. | .. |
|---|
| 3153 | 3162 | struct sadb_x_sec_ctx *sec_ctx; |
|---|
| 3154 | 3163 | struct xfrm_sec_ctx *xfrm_ctx; |
|---|
| 3155 | 3164 | int ctx_size = 0; |
|---|
| 3165 | + int alg_size = 0; |
|---|
| 3156 | 3166 | |
|---|
| 3157 | 3167 | sockaddr_size = pfkey_sockaddr_size(x->props.family); |
|---|
| 3158 | 3168 | if (!sockaddr_size) |
|---|
| .. | .. |
|---|
| 3164 | 3174 | sizeof(struct sadb_x_policy); |
|---|
| 3165 | 3175 | |
|---|
| 3166 | 3176 | if (x->id.proto == IPPROTO_AH) |
|---|
| 3167 | | - size += count_ah_combs(t); |
|---|
| 3177 | + alg_size = count_ah_combs(t); |
|---|
| 3168 | 3178 | else if (x->id.proto == IPPROTO_ESP) |
|---|
| 3169 | | - size += count_esp_combs(t); |
|---|
| 3179 | + alg_size = count_esp_combs(t); |
|---|
| 3170 | 3180 | |
|---|
| 3171 | 3181 | if ((xfrm_ctx = x->security)) { |
|---|
| 3172 | 3182 | ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len); |
|---|
| 3173 | 3183 | size += sizeof(struct sadb_x_sec_ctx) + ctx_size; |
|---|
| 3174 | 3184 | } |
|---|
| 3175 | 3185 | |
|---|
| 3176 | | - skb = alloc_skb(size + 16, GFP_ATOMIC); |
|---|
| 3186 | + skb = alloc_skb(size + alg_size + 16, GFP_ATOMIC); |
|---|
| 3177 | 3187 | if (skb == NULL) |
|---|
| 3178 | 3188 | return -ENOMEM; |
|---|
| 3179 | 3189 | |
|---|
| .. | .. |
|---|
| 3227 | 3237 | pol->sadb_x_policy_priority = xp->priority; |
|---|
| 3228 | 3238 | |
|---|
| 3229 | 3239 | /* Set sadb_comb's. */ |
|---|
| 3240 | + alg_size = 0; |
|---|
| 3230 | 3241 | if (x->id.proto == IPPROTO_AH) |
|---|
| 3231 | | - dump_ah_combs(skb, t); |
|---|
| 3242 | + alg_size = dump_ah_combs(skb, t); |
|---|
| 3232 | 3243 | else if (x->id.proto == IPPROTO_ESP) |
|---|
| 3233 | | - dump_esp_combs(skb, t); |
|---|
| 3244 | + alg_size = dump_esp_combs(skb, t); |
|---|
| 3245 | + |
|---|
| 3246 | + hdr->sadb_msg_len += alg_size / 8; |
|---|
| 3234 | 3247 | |
|---|
| 3235 | 3248 | /* security context */ |
|---|
| 3236 | 3249 | if (xfrm_ctx) { |
|---|
| .. | .. |
|---|
| 3747 | 3760 | .ioctl = sock_no_ioctl, |
|---|
| 3748 | 3761 | .listen = sock_no_listen, |
|---|
| 3749 | 3762 | .shutdown = sock_no_shutdown, |
|---|
| 3750 | | - .setsockopt = sock_no_setsockopt, |
|---|
| 3751 | | - .getsockopt = sock_no_getsockopt, |
|---|
| 3752 | 3763 | .mmap = sock_no_mmap, |
|---|
| 3753 | 3764 | .sendpage = sock_no_sendpage, |
|---|
| 3754 | 3765 | |
|---|