.. | .. |
---|
391 | 391 | u32 label; |
---|
392 | 392 | int err = 0; |
---|
393 | 393 | |
---|
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); |
---|
396 | 396 | if (err < 0) |
---|
397 | 397 | return err; |
---|
398 | 398 | |
---|
.. | .. |
---|
437 | 437 | { |
---|
438 | 438 | struct ifaddrlblmsg *ifal = nlmsg_data(nlh); |
---|
439 | 439 | ifal->ifal_family = AF_INET6; |
---|
| 440 | + ifal->__ifal_reserved = 0; |
---|
440 | 441 | ifal->ifal_prefixlen = prefixlen; |
---|
441 | 442 | ifal->ifal_flags = 0; |
---|
442 | 443 | ifal->ifal_index = ifindex; |
---|
.. | .. |
---|
466 | 467 | return 0; |
---|
467 | 468 | } |
---|
468 | 469 | |
---|
| 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 | + |
---|
469 | 495 | static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb) |
---|
470 | 496 | { |
---|
| 497 | + const struct nlmsghdr *nlh = cb->nlh; |
---|
471 | 498 | struct net *net = sock_net(skb->sk); |
---|
472 | 499 | struct ip6addrlbl_entry *p; |
---|
473 | 500 | int idx = 0, s_idx = cb->args[0]; |
---|
474 | 501 | 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 | + } |
---|
475 | 508 | |
---|
476 | 509 | rcu_read_lock(); |
---|
477 | 510 | hlist_for_each_entry_rcu(p, &net->ipv6.ip6addrlbl_table.head, list) { |
---|
.. | .. |
---|
479 | 512 | err = ip6addrlbl_fill(skb, p, |
---|
480 | 513 | net->ipv6.ip6addrlbl_table.seq, |
---|
481 | 514 | NETLINK_CB(cb->skb).portid, |
---|
482 | | - cb->nlh->nlmsg_seq, |
---|
| 515 | + nlh->nlmsg_seq, |
---|
483 | 516 | RTM_NEWADDRLABEL, |
---|
484 | 517 | NLM_F_MULTI); |
---|
485 | 518 | if (err < 0) |
---|
.. | .. |
---|
499 | 532 | + nla_total_size(4); /* IFAL_LABEL */ |
---|
500 | 533 | } |
---|
501 | 534 | |
---|
| 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 | + |
---|
502 | 579 | static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh, |
---|
503 | 580 | struct netlink_ext_ack *extack) |
---|
504 | 581 | { |
---|
.. | .. |
---|
511 | 588 | struct ip6addrlbl_entry *p; |
---|
512 | 589 | struct sk_buff *skb; |
---|
513 | 590 | |
---|
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); |
---|
516 | 592 | if (err < 0) |
---|
517 | 593 | return err; |
---|
518 | 594 | |
---|