summaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@gmail.com>2018-10-07 23:16:40 -0400
committerDavid S. Miller <davem@davemloft.net>2018-10-08 13:39:05 -0400
commitf2ae64bb6ba5b6a6e2271094a03d098821f4a699 (patch)
tree9e732a1db755a1aa00d8d34a2100b1dd06627dcd /net/ipv6
parent4a73e5e56d667e354926fe3f5f1aa75ff18bca51 (diff)
net/ipv6: Update ip6addrlbl_dump for strict data checking
Update ip6addrlbl_dump for strict data checking. If the flag is set, the dump request is expected to have an ifaddrlblmsg struct as the header. All elements of the struct are expected to be 0 and no attributes can be appended. Signed-off-by: David Ahern <dsahern@gmail.com> Acked-by: Christian Brauner <christian@brauner.io> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrlabel.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 1d6ced37ad71..0d1ee82ee55b 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -458,20 +458,52 @@ static int ip6addrlbl_fill(struct sk_buff *skb,
458 return 0; 458 return 0;
459} 459}
460 460
461static int ip6addrlbl_valid_dump_req(const struct nlmsghdr *nlh,
462 struct netlink_ext_ack *extack)
463{
464 struct ifaddrlblmsg *ifal;
465
466 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifal))) {
467 NL_SET_ERR_MSG_MOD(extack, "Invalid header for address label dump request");
468 return -EINVAL;
469 }
470
471 ifal = nlmsg_data(nlh);
472 if (ifal->__ifal_reserved || ifal->ifal_prefixlen ||
473 ifal->ifal_flags || ifal->ifal_index || ifal->ifal_seq) {
474 NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for address label dump request");
475 return -EINVAL;
476 }
477
478 if (nlmsg_attrlen(nlh, sizeof(*ifal))) {
479 NL_SET_ERR_MSG_MOD(extack, "Invalid data after header for address label dump requewst");
480 return -EINVAL;
481 }
482
483 return 0;
484}
485
461static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb) 486static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
462{ 487{
488 const struct nlmsghdr *nlh = cb->nlh;
463 struct net *net = sock_net(skb->sk); 489 struct net *net = sock_net(skb->sk);
464 struct ip6addrlbl_entry *p; 490 struct ip6addrlbl_entry *p;
465 int idx = 0, s_idx = cb->args[0]; 491 int idx = 0, s_idx = cb->args[0];
466 int err; 492 int err;
467 493
494 if (cb->strict_check) {
495 err = ip6addrlbl_valid_dump_req(nlh, cb->extack);
496 if (err < 0)
497 return err;
498 }
499
468 rcu_read_lock(); 500 rcu_read_lock();
469 hlist_for_each_entry_rcu(p, &net->ipv6.ip6addrlbl_table.head, list) { 501 hlist_for_each_entry_rcu(p, &net->ipv6.ip6addrlbl_table.head, list) {
470 if (idx >= s_idx) { 502 if (idx >= s_idx) {
471 err = ip6addrlbl_fill(skb, p, 503 err = ip6addrlbl_fill(skb, p,
472 net->ipv6.ip6addrlbl_table.seq, 504 net->ipv6.ip6addrlbl_table.seq,
473 NETLINK_CB(cb->skb).portid, 505 NETLINK_CB(cb->skb).portid,
474 cb->nlh->nlmsg_seq, 506 nlh->nlmsg_seq,
475 RTM_NEWADDRLABEL, 507 RTM_NEWADDRLABEL,
476 NLM_F_MULTI); 508 NLM_F_MULTI);
477 if (err < 0) 509 if (err < 0)