hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/net/ipv6/addrlabel.c
....@@ -391,8 +391,8 @@
391391 u32 label;
392392 int err = 0;
393393
394
- err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy,
395
- extack);
394
+ err = nlmsg_parse_deprecated(nlh, sizeof(*ifal), tb, IFAL_MAX,
395
+ ifal_policy, extack);
396396 if (err < 0)
397397 return err;
398398
....@@ -437,6 +437,7 @@
437437 {
438438 struct ifaddrlblmsg *ifal = nlmsg_data(nlh);
439439 ifal->ifal_family = AF_INET6;
440
+ ifal->__ifal_reserved = 0;
440441 ifal->ifal_prefixlen = prefixlen;
441442 ifal->ifal_flags = 0;
442443 ifal->ifal_index = ifindex;
....@@ -466,12 +467,44 @@
466467 return 0;
467468 }
468469
470
+static int ip6addrlbl_valid_dump_req(const struct nlmsghdr *nlh,
471
+ struct netlink_ext_ack *extack)
472
+{
473
+ struct ifaddrlblmsg *ifal;
474
+
475
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifal))) {
476
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for address label dump request");
477
+ return -EINVAL;
478
+ }
479
+
480
+ ifal = nlmsg_data(nlh);
481
+ if (ifal->__ifal_reserved || ifal->ifal_prefixlen ||
482
+ ifal->ifal_flags || ifal->ifal_index || ifal->ifal_seq) {
483
+ NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for address label dump request");
484
+ return -EINVAL;
485
+ }
486
+
487
+ if (nlmsg_attrlen(nlh, sizeof(*ifal))) {
488
+ NL_SET_ERR_MSG_MOD(extack, "Invalid data after header for address label dump request");
489
+ return -EINVAL;
490
+ }
491
+
492
+ return 0;
493
+}
494
+
469495 static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
470496 {
497
+ const struct nlmsghdr *nlh = cb->nlh;
471498 struct net *net = sock_net(skb->sk);
472499 struct ip6addrlbl_entry *p;
473500 int idx = 0, s_idx = cb->args[0];
474501 int err;
502
+
503
+ if (cb->strict_check) {
504
+ err = ip6addrlbl_valid_dump_req(nlh, cb->extack);
505
+ if (err < 0)
506
+ return err;
507
+ }
475508
476509 rcu_read_lock();
477510 hlist_for_each_entry_rcu(p, &net->ipv6.ip6addrlbl_table.head, list) {
....@@ -479,7 +512,7 @@
479512 err = ip6addrlbl_fill(skb, p,
480513 net->ipv6.ip6addrlbl_table.seq,
481514 NETLINK_CB(cb->skb).portid,
482
- cb->nlh->nlmsg_seq,
515
+ nlh->nlmsg_seq,
483516 RTM_NEWADDRLABEL,
484517 NLM_F_MULTI);
485518 if (err < 0)
....@@ -499,6 +532,50 @@
499532 + nla_total_size(4); /* IFAL_LABEL */
500533 }
501534
535
+static int ip6addrlbl_valid_get_req(struct sk_buff *skb,
536
+ const struct nlmsghdr *nlh,
537
+ struct nlattr **tb,
538
+ struct netlink_ext_ack *extack)
539
+{
540
+ struct ifaddrlblmsg *ifal;
541
+ int i, err;
542
+
543
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifal))) {
544
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for addrlabel get request");
545
+ return -EINVAL;
546
+ }
547
+
548
+ if (!netlink_strict_get_check(skb))
549
+ return nlmsg_parse_deprecated(nlh, sizeof(*ifal), tb,
550
+ IFAL_MAX, ifal_policy, extack);
551
+
552
+ ifal = nlmsg_data(nlh);
553
+ if (ifal->__ifal_reserved || ifal->ifal_flags || ifal->ifal_seq) {
554
+ NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for addrlabel get request");
555
+ return -EINVAL;
556
+ }
557
+
558
+ err = nlmsg_parse_deprecated_strict(nlh, sizeof(*ifal), tb, IFAL_MAX,
559
+ ifal_policy, extack);
560
+ if (err)
561
+ return err;
562
+
563
+ for (i = 0; i <= IFAL_MAX; i++) {
564
+ if (!tb[i])
565
+ continue;
566
+
567
+ switch (i) {
568
+ case IFAL_ADDRESS:
569
+ break;
570
+ default:
571
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in addrlabel get request");
572
+ return -EINVAL;
573
+ }
574
+ }
575
+
576
+ return 0;
577
+}
578
+
502579 static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
503580 struct netlink_ext_ack *extack)
504581 {
....@@ -511,8 +588,7 @@
511588 struct ip6addrlbl_entry *p;
512589 struct sk_buff *skb;
513590
514
- err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy,
515
- extack);
591
+ err = ip6addrlbl_valid_get_req(in_skb, nlh, tb, extack);
516592 if (err < 0)
517593 return err;
518594