@@ -683,51 +683,58 @@ static const struct nla_policy br_mdbe_attrs_pol[MDBE_ATTR_MAX + 1] = {
683683 [MDBE_ATTR_RTPROT ] = NLA_POLICY_MIN (NLA_U8 , RTPROT_STATIC ),
684684};
685685
686- static bool is_valid_mdb_entry ( struct br_mdb_entry * entry ,
687- struct netlink_ext_ack * extack )
686+ static int validate_mdb_entry ( const struct nlattr * attr ,
687+ struct netlink_ext_ack * extack )
688688{
689+ struct br_mdb_entry * entry = nla_data (attr );
690+
691+ if (nla_len (attr ) != sizeof (struct br_mdb_entry )) {
692+ NL_SET_ERR_MSG_MOD (extack , "Invalid MDBA_SET_ENTRY attribute length" );
693+ return - EINVAL ;
694+ }
695+
689696 if (entry -> ifindex == 0 ) {
690697 NL_SET_ERR_MSG_MOD (extack , "Zero entry ifindex is not allowed" );
691- return false ;
698+ return - EINVAL ;
692699 }
693700
694701 if (entry -> addr .proto == htons (ETH_P_IP )) {
695702 if (!ipv4_is_multicast (entry -> addr .u .ip4 )) {
696703 NL_SET_ERR_MSG_MOD (extack , "IPv4 entry group address is not multicast" );
697- return false ;
704+ return - EINVAL ;
698705 }
699706 if (ipv4_is_local_multicast (entry -> addr .u .ip4 )) {
700707 NL_SET_ERR_MSG_MOD (extack , "IPv4 entry group address is local multicast" );
701- return false ;
708+ return - EINVAL ;
702709 }
703710#if IS_ENABLED (CONFIG_IPV6 )
704711 } else if (entry -> addr .proto == htons (ETH_P_IPV6 )) {
705712 if (ipv6_addr_is_ll_all_nodes (& entry -> addr .u .ip6 )) {
706713 NL_SET_ERR_MSG_MOD (extack , "IPv6 entry group address is link-local all nodes" );
707- return false ;
714+ return - EINVAL ;
708715 }
709716#endif
710717 } else if (entry -> addr .proto == 0 ) {
711718 /* L2 mdb */
712719 if (!is_multicast_ether_addr (entry -> addr .u .mac_addr )) {
713720 NL_SET_ERR_MSG_MOD (extack , "L2 entry group is not multicast" );
714- return false ;
721+ return - EINVAL ;
715722 }
716723 } else {
717724 NL_SET_ERR_MSG_MOD (extack , "Unknown entry protocol" );
718- return false ;
725+ return - EINVAL ;
719726 }
720727
721728 if (entry -> state != MDB_PERMANENT && entry -> state != MDB_TEMPORARY ) {
722729 NL_SET_ERR_MSG_MOD (extack , "Unknown entry state" );
723- return false ;
730+ return - EINVAL ;
724731 }
725732 if (entry -> vid >= VLAN_VID_MASK ) {
726733 NL_SET_ERR_MSG_MOD (extack , "Invalid entry VLAN id" );
727- return false ;
734+ return - EINVAL ;
728735 }
729736
730- return true ;
737+ return 0 ;
731738}
732739
733740static bool is_valid_mdb_source (struct nlattr * attr , __be16 proto ,
@@ -1292,6 +1299,14 @@ static int br_mdb_config_attrs_init(struct nlattr *set_attrs,
12921299 return 0 ;
12931300}
12941301
1302+ static const struct nla_policy mdba_policy [MDBA_SET_ENTRY_MAX + 1 ] = {
1303+ [MDBA_SET_ENTRY_UNSPEC ] = { .strict_start_type = MDBA_SET_ENTRY_ATTRS + 1 },
1304+ [MDBA_SET_ENTRY ] = NLA_POLICY_VALIDATE_FN (NLA_BINARY ,
1305+ validate_mdb_entry ,
1306+ sizeof (struct br_mdb_entry )),
1307+ [MDBA_SET_ENTRY_ATTRS ] = { .type = NLA_NESTED },
1308+ };
1309+
12951310static int br_mdb_config_init (struct net * net , const struct nlmsghdr * nlh ,
12961311 struct br_mdb_config * cfg ,
12971312 struct netlink_ext_ack * extack )
@@ -1302,7 +1317,7 @@ static int br_mdb_config_init(struct net *net, const struct nlmsghdr *nlh,
13021317 int err ;
13031318
13041319 err = nlmsg_parse_deprecated (nlh , sizeof (* bpm ), tb ,
1305- MDBA_SET_ENTRY_MAX , NULL , extack );
1320+ MDBA_SET_ENTRY_MAX , mdba_policy , extack );
13061321 if (err )
13071322 return err ;
13081323
@@ -1344,14 +1359,8 @@ static int br_mdb_config_init(struct net *net, const struct nlmsghdr *nlh,
13441359 NL_SET_ERR_MSG_MOD (extack , "Missing MDBA_SET_ENTRY attribute" );
13451360 return - EINVAL ;
13461361 }
1347- if (nla_len (tb [MDBA_SET_ENTRY ]) != sizeof (struct br_mdb_entry )) {
1348- NL_SET_ERR_MSG_MOD (extack , "Invalid MDBA_SET_ENTRY attribute length" );
1349- return - EINVAL ;
1350- }
13511362
13521363 cfg -> entry = nla_data (tb [MDBA_SET_ENTRY ]);
1353- if (!is_valid_mdb_entry (cfg -> entry , extack ))
1354- return - EINVAL ;
13551364
13561365 if (cfg -> entry -> ifindex != cfg -> br -> dev -> ifindex ) {
13571366 struct net_device * pdev ;
0 commit comments