hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/key/af_key.c
....@@ -1,10 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * 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.
84 *
95 * Authors: Maxim Giryaev <gem@asplinux.ru>
106 * David S. Miller <davem@redhat.com>
....@@ -932,8 +928,7 @@
932928 pfkey_sockaddr_fill(&x->props.saddr, 0,
933929 (struct sockaddr *) (addr + 1),
934930 x->props.family);
935
- if (!addr->sadb_address_prefixlen)
936
- BUG();
931
+ BUG_ON(!addr->sadb_address_prefixlen);
937932
938933 /* dst address */
939934 addr = skb_put(skb, sizeof(struct sadb_address) + sockaddr_size);
....@@ -948,8 +943,7 @@
948943 pfkey_sockaddr_fill(&x->id.daddr, 0,
949944 (struct sockaddr *) (addr + 1),
950945 x->props.family);
951
- if (!addr->sadb_address_prefixlen)
952
- BUG();
946
+ BUG_ON(!addr->sadb_address_prefixlen);
953947
954948 if (!xfrm_addr_equal(&x->sel.saddr, &x->props.saddr,
955949 x->props.family)) {
....@@ -1707,9 +1701,12 @@
17071701 pfk->registered |= (1<<hdr->sadb_msg_satype);
17081702 }
17091703
1704
+ mutex_lock(&pfkey_mutex);
17101705 xfrm_probe_algs();
17111706
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
+
17131710 if (!supp_skb) {
17141711 if (hdr->sadb_msg_satype != SADB_SATYPE_UNSPEC)
17151712 pfk->registered &= ~(1<<hdr->sadb_msg_satype);
....@@ -1855,9 +1852,9 @@
18551852 if (ext_hdrs[SADB_X_EXT_FILTER - 1]) {
18561853 struct sadb_x_filter *xfilter = ext_hdrs[SADB_X_EXT_FILTER - 1];
18571854
1858
- if ((xfilter->sadb_x_filter_splen >=
1855
+ if ((xfilter->sadb_x_filter_splen >
18591856 (sizeof(xfrm_address_t) << 3)) ||
1860
- (xfilter->sadb_x_filter_dplen >=
1857
+ (xfilter->sadb_x_filter_dplen >
18611858 (sizeof(xfrm_address_t) << 3))) {
18621859 mutex_unlock(&pfk->dump_lock);
18631860 return -EINVAL;
....@@ -1947,7 +1944,8 @@
19471944 }
19481945
19491946 static int
1950
-parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1947
+parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_policy *pol,
1948
+ struct sadb_x_ipsecrequest *rq)
19511949 {
19521950 struct net *net = xp_net(xp);
19531951 struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr;
....@@ -1965,9 +1963,12 @@
19651963 if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0)
19661964 return -EINVAL;
19671965 t->mode = mode;
1968
- if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE)
1966
+ if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE) {
1967
+ if ((mode == XFRM_MODE_TUNNEL || mode == XFRM_MODE_BEET) &&
1968
+ pol->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND)
1969
+ return -EINVAL;
19691970 t->optional = 1;
1970
- else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) {
1971
+ } else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) {
19711972 t->reqid = rq->sadb_x_ipsecrequest_reqid;
19721973 if (t->reqid > IPSEC_MANUAL_REQID_MAX)
19731974 t->reqid = 0;
....@@ -2009,7 +2010,7 @@
20092010 rq->sadb_x_ipsecrequest_len < sizeof(*rq))
20102011 return -EINVAL;
20112012
2012
- if ((err = parse_ipsecrequest(xp, rq)) < 0)
2013
+ if ((err = parse_ipsecrequest(xp, pol, rq)) < 0)
20132014 return err;
20142015 len -= rq->sadb_x_ipsecrequest_len;
20152016 rq = (void*)((u8*)rq + rq->sadb_x_ipsecrequest_len);
....@@ -2019,7 +2020,7 @@
20192020
20202021 static inline int pfkey_xfrm_policy2sec_ctx_size(const struct xfrm_policy *xp)
20212022 {
2022
- struct xfrm_sec_ctx *xfrm_ctx = xp->security;
2023
+ struct xfrm_sec_ctx *xfrm_ctx = xp->security;
20232024
20242025 if (xfrm_ctx) {
20252026 int len = sizeof(struct sadb_x_sec_ctx);
....@@ -2413,7 +2414,7 @@
24132414 return err;
24142415 }
24152416
2416
- xp = xfrm_policy_bysel_ctx(net, DUMMY_MARK, 0, XFRM_POLICY_TYPE_MAIN,
2417
+ xp = xfrm_policy_bysel_ctx(net, &dummy_mark, 0, XFRM_POLICY_TYPE_MAIN,
24172418 pol->sadb_x_policy_dir - 1, &sel, pol_ctx,
24182419 1, &err);
24192420 security_xfrm_policy_free(pol_ctx);
....@@ -2633,7 +2634,7 @@
26332634 }
26342635
26352636 return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
2636
- kma ? &k : NULL, net, NULL);
2637
+ kma ? &k : NULL, net, NULL, 0);
26372638
26382639 out:
26392640 return err;
....@@ -2664,7 +2665,7 @@
26642665 return -EINVAL;
26652666
26662667 delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2);
2667
- xp = xfrm_policy_byid(net, DUMMY_MARK, 0, XFRM_POLICY_TYPE_MAIN,
2668
+ xp = xfrm_policy_byid(net, &dummy_mark, 0, XFRM_POLICY_TYPE_MAIN,
26682669 dir, pol->sadb_x_policy_id, delete, &err);
26692670 if (xp == NULL)
26702671 return -ENOENT;
....@@ -2836,6 +2837,10 @@
28362837 void *ext_hdrs[SADB_EXT_MAX];
28372838 int err;
28382839
2840
+ /* Non-zero return value of pfkey_broadcast() does not always signal
2841
+ * an error and even on an actual error we may still want to process
2842
+ * the message so rather ignore the return value.
2843
+ */
28392844 pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL,
28402845 BROADCAST_PROMISC_ONLY, NULL, sock_net(sk));
28412846
....@@ -2944,9 +2949,10 @@
29442949 return sz + sizeof(struct sadb_prop);
29452950 }
29462951
2947
-static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
2952
+static int dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
29482953 {
29492954 struct sadb_prop *p;
2955
+ int sz = 0;
29502956 int i;
29512957
29522958 p = skb_put(skb, sizeof(struct sadb_prop));
....@@ -2974,13 +2980,17 @@
29742980 c->sadb_comb_soft_addtime = 20*60*60;
29752981 c->sadb_comb_hard_usetime = 8*60*60;
29762982 c->sadb_comb_soft_usetime = 7*60*60;
2983
+ sz += sizeof(*c);
29772984 }
29782985 }
2986
+
2987
+ return sz + sizeof(*p);
29792988 }
29802989
2981
-static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
2990
+static int dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
29822991 {
29832992 struct sadb_prop *p;
2993
+ int sz = 0;
29842994 int i, k;
29852995
29862996 p = skb_put(skb, sizeof(struct sadb_prop));
....@@ -3022,8 +3032,11 @@
30223032 c->sadb_comb_soft_addtime = 20*60*60;
30233033 c->sadb_comb_hard_usetime = 8*60*60;
30243034 c->sadb_comb_soft_usetime = 7*60*60;
3035
+ sz += sizeof(*c);
30253036 }
30263037 }
3038
+
3039
+ return sz + sizeof(*p);
30273040 }
30283041
30293042 static int key_notify_policy_expire(struct xfrm_policy *xp, const struct km_event *c)
....@@ -3153,6 +3166,7 @@
31533166 struct sadb_x_sec_ctx *sec_ctx;
31543167 struct xfrm_sec_ctx *xfrm_ctx;
31553168 int ctx_size = 0;
3169
+ int alg_size = 0;
31563170
31573171 sockaddr_size = pfkey_sockaddr_size(x->props.family);
31583172 if (!sockaddr_size)
....@@ -3164,16 +3178,16 @@
31643178 sizeof(struct sadb_x_policy);
31653179
31663180 if (x->id.proto == IPPROTO_AH)
3167
- size += count_ah_combs(t);
3181
+ alg_size = count_ah_combs(t);
31683182 else if (x->id.proto == IPPROTO_ESP)
3169
- size += count_esp_combs(t);
3183
+ alg_size = count_esp_combs(t);
31703184
31713185 if ((xfrm_ctx = x->security)) {
31723186 ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len);
31733187 size += sizeof(struct sadb_x_sec_ctx) + ctx_size;
31743188 }
31753189
3176
- skb = alloc_skb(size + 16, GFP_ATOMIC);
3190
+ skb = alloc_skb(size + alg_size + 16, GFP_ATOMIC);
31773191 if (skb == NULL)
31783192 return -ENOMEM;
31793193
....@@ -3227,10 +3241,13 @@
32273241 pol->sadb_x_policy_priority = xp->priority;
32283242
32293243 /* Set sadb_comb's. */
3244
+ alg_size = 0;
32303245 if (x->id.proto == IPPROTO_AH)
3231
- dump_ah_combs(skb, t);
3246
+ alg_size = dump_ah_combs(skb, t);
32323247 else if (x->id.proto == IPPROTO_ESP)
3233
- dump_esp_combs(skb, t);
3248
+ alg_size = dump_esp_combs(skb, t);
3249
+
3250
+ hdr->sadb_msg_len += alg_size / 8;
32343251
32353252 /* security context */
32363253 if (xfrm_ctx) {
....@@ -3747,8 +3764,6 @@
37473764 .ioctl = sock_no_ioctl,
37483765 .listen = sock_no_listen,
37493766 .shutdown = sock_no_shutdown,
3750
- .setsockopt = sock_no_setsockopt,
3751
- .getsockopt = sock_no_getsockopt,
37523767 .mmap = sock_no_mmap,
37533768 .sendpage = sock_no_sendpage,
37543769