hc
2024-10-09 05e59e5fb0064c97a1c10921ecd549f2d4a58565
kernel/net/ipv6/seg6.c
....@@ -1,14 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * SR-IPv6 implementation
34 *
45 * Author:
56 * David Lebrun <david.lebrun@uclouvain.be>
6
- *
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * as published by the Free Software Foundation; either version
11
- * 2 of the License, or (at your option) any later version.
127 */
138
149 #include <linux/errno.h>
....@@ -30,10 +25,11 @@
3025 #include <net/seg6_hmac.h>
3126 #endif
3227
33
-bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len)
28
+bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len, bool reduced)
3429 {
35
- int trailing;
3630 unsigned int tlv_offset;
31
+ int max_last_entry;
32
+ int trailing;
3733
3834 if (srh->type != IPV6_SRCRT_TYPE_4)
3935 return false;
....@@ -41,8 +37,17 @@
4137 if (((srh->hdrlen + 1) << 3) != len)
4238 return false;
4339
44
- if (srh->segments_left > srh->first_segment)
40
+ if (!reduced && srh->segments_left > srh->first_segment) {
4541 return false;
42
+ } else {
43
+ max_last_entry = (srh->hdrlen / 2) - 1;
44
+
45
+ if (srh->first_segment > max_last_entry)
46
+ return false;
47
+
48
+ if (srh->segments_left > srh->first_segment + 1)
49
+ return false;
50
+ }
4651
4752 tlv_offset = sizeof(*srh) + ((srh->first_segment + 1) << 4);
4853
....@@ -126,6 +131,11 @@
126131 }
127132
128133 if (!info->attrs[SEG6_ATTR_SECRET]) {
134
+ err = -EINVAL;
135
+ goto out_unlock;
136
+ }
137
+
138
+ if (slen > nla_len(info->attrs[SEG6_ATTR_SECRET])) {
129139 err = -EINVAL;
130140 goto out_unlock;
131141 }
....@@ -398,28 +408,28 @@
398408 static const struct genl_ops seg6_genl_ops[] = {
399409 {
400410 .cmd = SEG6_CMD_SETHMAC,
411
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
401412 .doit = seg6_genl_sethmac,
402
- .policy = seg6_genl_policy,
403413 .flags = GENL_ADMIN_PERM,
404414 },
405415 {
406416 .cmd = SEG6_CMD_DUMPHMAC,
417
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
407418 .start = seg6_genl_dumphmac_start,
408419 .dumpit = seg6_genl_dumphmac,
409420 .done = seg6_genl_dumphmac_done,
410
- .policy = seg6_genl_policy,
411421 .flags = GENL_ADMIN_PERM,
412422 },
413423 {
414424 .cmd = SEG6_CMD_SET_TUNSRC,
425
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
415426 .doit = seg6_genl_set_tunsrc,
416
- .policy = seg6_genl_policy,
417427 .flags = GENL_ADMIN_PERM,
418428 },
419429 {
420430 .cmd = SEG6_CMD_GET_TUNSRC,
431
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
421432 .doit = seg6_genl_get_tunsrc,
422
- .policy = seg6_genl_policy,
423433 .flags = GENL_ADMIN_PERM,
424434 },
425435 };
....@@ -429,6 +439,7 @@
429439 .name = SEG6_GENL_NAME,
430440 .version = SEG6_GENL_VERSION,
431441 .maxattr = SEG6_ATTR_MAX,
442
+ .policy = seg6_genl_policy,
432443 .netnsok = true,
433444 .parallel_ops = true,
434445 .ops = seg6_genl_ops,
....@@ -438,7 +449,7 @@
438449
439450 int __init seg6_init(void)
440451 {
441
- int err = -ENOMEM;
452
+ int err;
442453
443454 err = genl_register_family(&seg6_genl_family);
444455 if (err)