hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/net/xfrm/xfrm_user.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* xfrm_user.c: User interface to configure xfrm engine.
23 *
34 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
....@@ -521,7 +522,7 @@
521522 struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
522523 struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
523524
524
- if (re) {
525
+ if (re && x->replay_esn && x->preplay_esn) {
525526 struct xfrm_replay_state_esn *replay_esn;
526527 replay_esn = nla_data(re);
527528 memcpy(x->replay_esn, replay_esn,
....@@ -620,13 +621,8 @@
620621
621622 xfrm_smark_init(attrs, &x->props.smark);
622623
623
- if (attrs[XFRMA_IF_ID]) {
624
+ if (attrs[XFRMA_IF_ID])
624625 x->if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
625
- if (!x->if_id) {
626
- err = -EINVAL;
627
- goto error;
628
- }
629
- }
630626
631627 err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV]);
632628 if (err)
....@@ -1043,8 +1039,8 @@
10431039 u8 proto = 0;
10441040 int err;
10451041
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);
10481044 if (err < 0)
10491045 return err;
10501046
....@@ -1053,6 +1049,15 @@
10531049 sizeof(*filter), GFP_KERNEL);
10541050 if (filter == NULL)
10551051 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
+ }
10561061 }
10571062
10581063 if (attrs[XFRMA_PROTO])
....@@ -1357,13 +1362,8 @@
13571362
13581363 mark = xfrm_mark_get(attrs, &m);
13591364
1360
- if (attrs[XFRMA_IF_ID]) {
1365
+ if (attrs[XFRMA_IF_ID])
13611366 if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
1362
- if (!if_id) {
1363
- err = -EINVAL;
1364
- goto out_noput;
1365
- }
1366
- }
13671367
13681368 if (p->info.seq) {
13691369 x = xfrm_find_acq_byseq(net, mark, p->info.seq);
....@@ -1676,13 +1676,8 @@
16761676
16771677 xfrm_mark_get(attrs, &xp->mark);
16781678
1679
- if (attrs[XFRMA_IF_ID]) {
1679
+ if (attrs[XFRMA_IF_ID])
16801680 xp->if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
1681
- if (!xp->if_id) {
1682
- err = -EINVAL;
1683
- goto error;
1684
- }
1685
- }
16861681
16871682 return xp;
16881683 error:
....@@ -1926,7 +1921,6 @@
19261921 struct km_event c;
19271922 int delete;
19281923 struct xfrm_mark m;
1929
- u32 mark = xfrm_mark_get(attrs, &m);
19301924 u32 if_id = 0;
19311925
19321926 p = nlmsg_data(nlh);
....@@ -1943,8 +1937,11 @@
19431937 if (attrs[XFRMA_IF_ID])
19441938 if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
19451939
1940
+ xfrm_mark_get(attrs, &m);
1941
+
19461942 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);
19481945 else {
19491946 struct nlattr *rt = attrs[XFRMA_SEC_CTX];
19501947 struct xfrm_sec_ctx *ctx;
....@@ -1961,8 +1958,8 @@
19611958 if (err)
19621959 return err;
19631960 }
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);
19661963 security_xfrm_policy_free(ctx);
19671964 }
19681965 if (xp == NULL)
....@@ -2229,7 +2226,6 @@
22292226 u8 type = XFRM_POLICY_TYPE_MAIN;
22302227 int err = -ENOENT;
22312228 struct xfrm_mark m;
2232
- u32 mark = xfrm_mark_get(attrs, &m);
22332229 u32 if_id = 0;
22342230
22352231 err = copy_from_user_policy_type(&type, attrs);
....@@ -2243,8 +2239,11 @@
22432239 if (attrs[XFRMA_IF_ID])
22442240 if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
22452241
2242
+ xfrm_mark_get(attrs, &m);
2243
+
22462244 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);
22482247 else {
22492248 struct nlattr *rt = attrs[XFRMA_SEC_CTX];
22502249 struct xfrm_sec_ctx *ctx;
....@@ -2261,7 +2260,7 @@
22612260 if (err)
22622261 return err;
22632262 }
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,
22652264 &p->sel, ctx, 0, &err);
22662265 security_xfrm_policy_free(ctx);
22672266 }
....@@ -2433,6 +2432,7 @@
24332432 int n = 0;
24342433 struct net *net = sock_net(skb->sk);
24352434 struct xfrm_encap_tmpl *encap = NULL;
2435
+ u32 if_id = 0;
24362436
24372437 if (attrs[XFRMA_MIGRATE] == NULL)
24382438 return -EINVAL;
....@@ -2457,7 +2457,10 @@
24572457 return 0;
24582458 }
24592459
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);
24612464
24622465 kfree(encap);
24632466
....@@ -2630,7 +2633,7 @@
26302633 [XFRMA_ALG_COMP] = { .len = sizeof(struct xfrm_algo) },
26312634 [XFRMA_ENCAP] = { .len = sizeof(struct xfrm_encap_tmpl) },
26322635 [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) },
26342637 [XFRMA_LTIME_VAL] = { .len = sizeof(struct xfrm_lifetime_cur) },
26352638 [XFRMA_REPLAY_VAL] = { .len = sizeof(struct xfrm_replay_state) },
26362639 [XFRMA_REPLAY_THRESH] = { .type = NLA_U32 },
....@@ -2751,9 +2754,9 @@
27512754 goto err;
27522755 }
27532756
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);
27572760 if (err < 0)
27582761 goto err;
27592762
....@@ -2764,6 +2767,16 @@
27642767
27652768 err = link->doit(skb, nlh, attrs);
27662769
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
+
27672780 err:
27682781 kvfree(nlh64);
27692782 return err;