Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

genetlink: start to validate reserved header bytes

We had historically not checked that genlmsghdr.reserved
is 0 on input which prevents us from using those precious
bytes in the future.

One use case would be to extend the cmd field, which is
currently just 8 bits wide and 256 is not a lot of commands
for some core families.

To make sure that new families do the right thing by default
put the onus of opting out of validation on existing families.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Paul Moore <paul@paul-moore.com> (NetLabel)
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jakub Kicinski and committed by
David S. Miller
9c5d03d3 53a40680

+56 -2
+1
drivers/block/nbd.c
··· 2322 2322 .module = THIS_MODULE, 2323 2323 .small_ops = nbd_connect_genl_ops, 2324 2324 .n_small_ops = ARRAY_SIZE(nbd_connect_genl_ops), 2325 + .resv_start_op = NBD_CMD_STATUS + 1, 2325 2326 .maxattr = NBD_ATTR_MAX, 2326 2327 .policy = nbd_attr_policy, 2327 2328 .mcgrps = nbd_mcast_grps,
+1
drivers/net/gtp.c
··· 1859 1859 .module = THIS_MODULE, 1860 1860 .small_ops = gtp_genl_ops, 1861 1861 .n_small_ops = ARRAY_SIZE(gtp_genl_ops), 1862 + .resv_start_op = GTP_CMD_ECHOREQ + 1, 1862 1863 .mcgrps = gtp_genl_mcgrps, 1863 1864 .n_mcgrps = ARRAY_SIZE(gtp_genl_mcgrps), 1864 1865 };
+1
drivers/net/ieee802154/mac802154_hwsim.c
··· 630 630 .module = THIS_MODULE, 631 631 .small_ops = hwsim_nl_ops, 632 632 .n_small_ops = ARRAY_SIZE(hwsim_nl_ops), 633 + .resv_start_op = MAC802154_HWSIM_CMD_NEW_EDGE + 1, 633 634 .mcgrps = hwsim_mcgrps, 634 635 .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps), 635 636 };
+1
drivers/net/macsec.c
··· 3404 3404 .module = THIS_MODULE, 3405 3405 .small_ops = macsec_genl_ops, 3406 3406 .n_small_ops = ARRAY_SIZE(macsec_genl_ops), 3407 + .resv_start_op = MACSEC_CMD_UPD_OFFLOAD + 1, 3407 3408 }; 3408 3409 3409 3410 static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
+1
drivers/net/team/team.c
··· 2840 2840 .module = THIS_MODULE, 2841 2841 .small_ops = team_nl_ops, 2842 2842 .n_small_ops = ARRAY_SIZE(team_nl_ops), 2843 + .resv_start_op = TEAM_CMD_PORT_LIST_GET + 1, 2843 2844 .mcgrps = team_nl_mcgrps, 2844 2845 .n_mcgrps = ARRAY_SIZE(team_nl_mcgrps), 2845 2846 };
+1
drivers/net/wireguard/netlink.c
··· 621 621 static struct genl_family genl_family __ro_after_init = { 622 622 .ops = genl_ops, 623 623 .n_ops = ARRAY_SIZE(genl_ops), 624 + .resv_start_op = WG_CMD_SET_DEVICE + 1, 624 625 .name = WG_GENL_NAME, 625 626 .version = WG_GENL_VERSION, 626 627 .maxattr = WGDEVICE_A_MAX,
+1
drivers/net/wireless/mac80211_hwsim.c
··· 5288 5288 .module = THIS_MODULE, 5289 5289 .small_ops = hwsim_ops, 5290 5290 .n_small_ops = ARRAY_SIZE(hwsim_ops), 5291 + .resv_start_op = HWSIM_CMD_DEL_MAC_ADDR + 1, 5291 5292 .mcgrps = hwsim_mcgrps, 5292 5293 .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps), 5293 5294 };
+1
drivers/target/target_core_user.c
··· 486 486 .netnsok = true, 487 487 .small_ops = tcmu_genl_ops, 488 488 .n_small_ops = ARRAY_SIZE(tcmu_genl_ops), 489 + .resv_start_op = TCMU_CMD_SET_FEATURES + 1, 489 490 }; 490 491 491 492 #define tcmu_cmd_set_dbi_cur(cmd, index) ((cmd)->dbi_cur = (index))
+1
drivers/thermal/thermal_netlink.c
··· 693 693 .policy = thermal_genl_policy, 694 694 .small_ops = thermal_genl_ops, 695 695 .n_small_ops = ARRAY_SIZE(thermal_genl_ops), 696 + .resv_start_op = THERMAL_GENL_CMD_CDEV_GET + 1, 696 697 .mcgrps = thermal_genl_mcgrps, 697 698 .n_mcgrps = ARRAY_SIZE(thermal_genl_mcgrps), 698 699 };
+1
drivers/vdpa/vdpa.c
··· 1183 1183 .module = THIS_MODULE, 1184 1184 .ops = vdpa_nl_ops, 1185 1185 .n_ops = ARRAY_SIZE(vdpa_nl_ops), 1186 + .resv_start_op = VDPA_CMD_DEV_VSTATS_GET + 1, 1186 1187 }; 1187 1188 1188 1189 static int vdpa_init(void)
+1
fs/cifs/netlink.c
··· 51 51 .policy = cifs_genl_policy, 52 52 .ops = cifs_genl_ops, 53 53 .n_ops = ARRAY_SIZE(cifs_genl_ops), 54 + .resv_start_op = CIFS_GENL_CMD_SWN_NOTIFY + 1, 54 55 .mcgrps = cifs_genl_mcgrps, 55 56 .n_mcgrps = ARRAY_SIZE(cifs_genl_mcgrps), 56 57 };
+1
fs/dlm/netlink.c
··· 75 75 .version = DLM_GENL_VERSION, 76 76 .small_ops = dlm_nl_ops, 77 77 .n_small_ops = ARRAY_SIZE(dlm_nl_ops), 78 + .resv_start_op = DLM_CMD_HELLO + 1, 78 79 .module = THIS_MODULE, 79 80 }; 80 81
+1
fs/ksmbd/transport_ipc.c
··· 197 197 .module = THIS_MODULE, 198 198 .ops = ksmbd_genl_ops, 199 199 .n_ops = ARRAY_SIZE(ksmbd_genl_ops), 200 + .resv_start_op = KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE + 1, 200 201 }; 201 202 202 203 static void ksmbd_nl_init_fixup(void)
+1
include/linux/genl_magic_func.h
··· 294 294 .ops = ZZZ_genl_ops, 295 295 .n_ops = ARRAY_SIZE(ZZZ_genl_ops), 296 296 .mcgrps = ZZZ_genl_mcgrps, 297 + .resv_start_op = 42, /* drbd is currently the only user */ 297 298 .n_mcgrps = ARRAY_SIZE(ZZZ_genl_mcgrps), 298 299 .module = THIS_MODULE, 299 300 };
+3
include/net/genetlink.h
··· 39 39 * undo operations done by pre_doit, for example release locks 40 40 * @mcgrps: multicast groups used by this family 41 41 * @n_mcgrps: number of multicast groups 42 + * @resv_start_op: first operation for which reserved fields of the header 43 + * can be validated, new families should leave this field at zero 42 44 * @mcgrp_offset: starting number of multicast group IDs in this family 43 45 * (private) 44 46 * @ops: the operations supported by this family ··· 60 58 u8 n_ops; 61 59 u8 n_small_ops; 62 60 u8 n_mcgrps; 61 + u8 resv_start_op; 63 62 const struct nla_policy *policy; 64 63 int (*pre_doit)(const struct genl_ops *ops, 65 64 struct sk_buff *skb,
+1
kernel/taskstats.c
··· 688 688 .module = THIS_MODULE, 689 689 .ops = taskstats_ops, 690 690 .n_ops = ARRAY_SIZE(taskstats_ops), 691 + .resv_start_op = CGROUPSTATS_CMD_GET + 1, 691 692 .netnsok = true, 692 693 }; 693 694
+1
net/batman-adv/netlink.c
··· 1493 1493 .module = THIS_MODULE, 1494 1494 .small_ops = batadv_netlink_ops, 1495 1495 .n_small_ops = ARRAY_SIZE(batadv_netlink_ops), 1496 + .resv_start_op = BATADV_CMD_SET_VLAN + 1, 1496 1497 .mcgrps = batadv_netlink_mcgrps, 1497 1498 .n_mcgrps = ARRAY_SIZE(batadv_netlink_mcgrps), 1498 1499 };
+1
net/core/devlink.c
··· 9610 9610 .module = THIS_MODULE, 9611 9611 .small_ops = devlink_nl_ops, 9612 9612 .n_small_ops = ARRAY_SIZE(devlink_nl_ops), 9613 + .resv_start_op = DEVLINK_CMD_SELFTESTS_RUN + 1, 9613 9614 .mcgrps = devlink_nl_mcgrps, 9614 9615 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps), 9615 9616 };
+1
net/core/drop_monitor.c
··· 1645 1645 .module = THIS_MODULE, 1646 1646 .small_ops = dropmon_ops, 1647 1647 .n_small_ops = ARRAY_SIZE(dropmon_ops), 1648 + .resv_start_op = NET_DM_CMD_STATS_GET + 1, 1648 1649 .mcgrps = dropmon_mcgrps, 1649 1650 .n_mcgrps = ARRAY_SIZE(dropmon_mcgrps), 1650 1651 };
+1
net/ethtool/netlink.c
··· 1033 1033 .parallel_ops = true, 1034 1034 .ops = ethtool_genl_ops, 1035 1035 .n_ops = ARRAY_SIZE(ethtool_genl_ops), 1036 + .resv_start_op = ETHTOOL_MSG_MODULE_GET + 1, 1036 1037 .mcgrps = ethtool_nl_mcgrps, 1037 1038 .n_mcgrps = ARRAY_SIZE(ethtool_nl_mcgrps), 1038 1039 };
+1
net/hsr/hsr_netlink.c
··· 522 522 .module = THIS_MODULE, 523 523 .small_ops = hsr_ops, 524 524 .n_small_ops = ARRAY_SIZE(hsr_ops), 525 + .resv_start_op = HSR_C_SET_NODE_LIST + 1, 525 526 .mcgrps = hsr_mcgrps, 526 527 .n_mcgrps = ARRAY_SIZE(hsr_mcgrps), 527 528 };
+1
net/ieee802154/netlink.c
··· 132 132 .module = THIS_MODULE, 133 133 .small_ops = ieee802154_ops, 134 134 .n_small_ops = ARRAY_SIZE(ieee802154_ops), 135 + .resv_start_op = IEEE802154_LLSEC_DEL_SECLEVEL + 1, 135 136 .mcgrps = ieee802154_mcgrps, 136 137 .n_mcgrps = ARRAY_SIZE(ieee802154_mcgrps), 137 138 };
+1
net/ieee802154/nl802154.c
··· 2500 2500 .module = THIS_MODULE, 2501 2501 .ops = nl802154_ops, 2502 2502 .n_ops = ARRAY_SIZE(nl802154_ops), 2503 + .resv_start_op = NL802154_CMD_DEL_SEC_LEVEL + 1, 2503 2504 .mcgrps = nl802154_mcgrps, 2504 2505 .n_mcgrps = ARRAY_SIZE(nl802154_mcgrps), 2505 2506 };
+1
net/ipv4/fou.c
··· 928 928 .module = THIS_MODULE, 929 929 .small_ops = fou_nl_ops, 930 930 .n_small_ops = ARRAY_SIZE(fou_nl_ops), 931 + .resv_start_op = FOU_CMD_GET + 1, 931 932 }; 932 933 933 934 size_t fou_encap_hlen(struct ip_tunnel_encap *e)
+1
net/ipv4/tcp_metrics.c
··· 969 969 .module = THIS_MODULE, 970 970 .small_ops = tcp_metrics_nl_ops, 971 971 .n_small_ops = ARRAY_SIZE(tcp_metrics_nl_ops), 972 + .resv_start_op = TCP_METRICS_CMD_DEL + 1, 972 973 }; 973 974 974 975 static unsigned int tcpmhash_entries;
+1
net/ipv6/ila/ila_main.c
··· 55 55 .module = THIS_MODULE, 56 56 .ops = ila_nl_ops, 57 57 .n_ops = ARRAY_SIZE(ila_nl_ops), 58 + .resv_start_op = ILA_CMD_FLUSH + 1, 58 59 }; 59 60 60 61 static __net_init int ila_init_net(struct net *net)
+1
net/ipv6/ioam6.c
··· 619 619 .parallel_ops = true, 620 620 .ops = ioam6_genl_ops, 621 621 .n_ops = ARRAY_SIZE(ioam6_genl_ops), 622 + .resv_start_op = IOAM6_CMD_NS_SET_SCHEMA + 1, 622 623 .module = THIS_MODULE, 623 624 }; 624 625
+1
net/ipv6/seg6.c
··· 499 499 .parallel_ops = true, 500 500 .ops = seg6_genl_ops, 501 501 .n_ops = ARRAY_SIZE(seg6_genl_ops), 502 + .resv_start_op = SEG6_CMD_GET_TUNSRC + 1, 502 503 .module = THIS_MODULE, 503 504 }; 504 505
+1
net/l2tp/l2tp_netlink.c
··· 989 989 .module = THIS_MODULE, 990 990 .small_ops = l2tp_nl_ops, 991 991 .n_small_ops = ARRAY_SIZE(l2tp_nl_ops), 992 + .resv_start_op = L2TP_CMD_SESSION_GET + 1, 992 993 .mcgrps = l2tp_multicast_group, 993 994 .n_mcgrps = ARRAY_SIZE(l2tp_multicast_group), 994 995 };
+1
net/mptcp/pm_netlink.c
··· 2280 2280 .module = THIS_MODULE, 2281 2281 .small_ops = mptcp_pm_ops, 2282 2282 .n_small_ops = ARRAY_SIZE(mptcp_pm_ops), 2283 + .resv_start_op = MPTCP_PM_CMD_SUBFLOW_DESTROY + 1, 2283 2284 .mcgrps = mptcp_pm_mcgrps, 2284 2285 .n_mcgrps = ARRAY_SIZE(mptcp_pm_mcgrps), 2285 2286 };
+1
net/ncsi/ncsi-netlink.c
··· 768 768 .module = THIS_MODULE, 769 769 .small_ops = ncsi_ops, 770 770 .n_small_ops = ARRAY_SIZE(ncsi_ops), 771 + .resv_start_op = NCSI_CMD_SET_CHANNEL_MASK + 1, 771 772 }; 772 773 773 774 static int __init ncsi_init_netlink(void)
+1
net/netfilter/ipvs/ip_vs_ctl.c
··· 4005 4005 .module = THIS_MODULE, 4006 4006 .small_ops = ip_vs_genl_ops, 4007 4007 .n_small_ops = ARRAY_SIZE(ip_vs_genl_ops), 4008 + .resv_start_op = IPVS_CMD_FLUSH + 1, 4008 4009 }; 4009 4010 4010 4011 static int __init ip_vs_genl_register(void)
+1
net/netlabel/netlabel_calipso.c
··· 344 344 .module = THIS_MODULE, 345 345 .small_ops = netlbl_calipso_ops, 346 346 .n_small_ops = ARRAY_SIZE(netlbl_calipso_ops), 347 + .resv_start_op = NLBL_CALIPSO_C_LISTALL + 1, 347 348 }; 348 349 349 350 /* NetLabel Generic NETLINK Protocol Functions
+1
net/netlabel/netlabel_cipso_v4.c
··· 767 767 .module = THIS_MODULE, 768 768 .small_ops = netlbl_cipsov4_ops, 769 769 .n_small_ops = ARRAY_SIZE(netlbl_cipsov4_ops), 770 + .resv_start_op = NLBL_CIPSOV4_C_LISTALL + 1, 770 771 }; 771 772 772 773 /*
+1
net/netlabel/netlabel_mgmt.c
··· 826 826 .module = THIS_MODULE, 827 827 .small_ops = netlbl_mgmt_genl_ops, 828 828 .n_small_ops = ARRAY_SIZE(netlbl_mgmt_genl_ops), 829 + .resv_start_op = NLBL_MGMT_C_VERSION + 1, 829 830 }; 830 831 831 832 /*
+1
net/netlabel/netlabel_unlabeled.c
··· 1374 1374 .module = THIS_MODULE, 1375 1375 .small_ops = netlbl_unlabel_genl_ops, 1376 1376 .n_small_ops = ARRAY_SIZE(netlbl_unlabel_genl_ops), 1377 + .resv_start_op = NLBL_UNLABEL_C_STATICLISTDEF + 1, 1377 1378 }; 1378 1379 1379 1380 /*
+4
net/netlink/genetlink.c
··· 757 757 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 758 758 return -EINVAL; 759 759 760 + if (hdr->cmd >= family->resv_start_op && hdr->reserved) 761 + return -EINVAL; 762 + 760 763 if (genl_get_cmd(hdr->cmd, family, &op)) 761 764 return -EOPNOTSUPP; 762 765 ··· 1351 1348 .module = THIS_MODULE, 1352 1349 .ops = genl_ctrl_ops, 1353 1350 .n_ops = ARRAY_SIZE(genl_ctrl_ops), 1351 + .resv_start_op = CTRL_CMD_GETPOLICY + 1, 1354 1352 .mcgrps = genl_ctrl_groups, 1355 1353 .n_mcgrps = ARRAY_SIZE(genl_ctrl_groups), 1356 1354 .id = GENL_ID_CTRL,
+1
net/nfc/netlink.c
··· 1783 1783 .module = THIS_MODULE, 1784 1784 .ops = nfc_genl_ops, 1785 1785 .n_ops = ARRAY_SIZE(nfc_genl_ops), 1786 + .resv_start_op = NFC_CMD_DEACTIVATE_TARGET + 1, 1786 1787 .mcgrps = nfc_genl_mcgrps, 1787 1788 .n_mcgrps = ARRAY_SIZE(nfc_genl_mcgrps), 1788 1789 };
+1
net/openvswitch/conntrack.c
··· 2283 2283 .parallel_ops = true, 2284 2284 .small_ops = ct_limit_genl_ops, 2285 2285 .n_small_ops = ARRAY_SIZE(ct_limit_genl_ops), 2286 + .resv_start_op = OVS_CT_LIMIT_CMD_GET + 1, 2286 2287 .mcgrps = &ovs_ct_limit_multicast_group, 2287 2288 .n_mcgrps = 1, 2288 2289 .module = THIS_MODULE,
+3
net/openvswitch/datapath.c
··· 692 692 .parallel_ops = true, 693 693 .small_ops = dp_packet_genl_ops, 694 694 .n_small_ops = ARRAY_SIZE(dp_packet_genl_ops), 695 + .resv_start_op = OVS_PACKET_CMD_EXECUTE + 1, 695 696 .module = THIS_MODULE, 696 697 }; 697 698 ··· 1510 1509 .parallel_ops = true, 1511 1510 .small_ops = dp_flow_genl_ops, 1512 1511 .n_small_ops = ARRAY_SIZE(dp_flow_genl_ops), 1512 + .resv_start_op = OVS_FLOW_CMD_SET + 1, 1513 1513 .mcgrps = &ovs_dp_flow_multicast_group, 1514 1514 .n_mcgrps = 1, 1515 1515 .module = THIS_MODULE, ··· 2053 2051 .parallel_ops = true, 2054 2052 .small_ops = dp_datapath_genl_ops, 2055 2053 .n_small_ops = ARRAY_SIZE(dp_datapath_genl_ops), 2054 + .resv_start_op = OVS_DP_CMD_SET + 1, 2056 2055 .mcgrps = &ovs_dp_datapath_multicast_group, 2057 2056 .n_mcgrps = 1, 2058 2057 .module = THIS_MODULE,
+1
net/openvswitch/meter.c
··· 720 720 .parallel_ops = true, 721 721 .small_ops = dp_meter_genl_ops, 722 722 .n_small_ops = ARRAY_SIZE(dp_meter_genl_ops), 723 + .resv_start_op = OVS_METER_CMD_GET + 1, 723 724 .mcgrps = &ovs_meter_multicast_group, 724 725 .n_mcgrps = 1, 725 726 .module = THIS_MODULE,
+1
net/psample/psample.c
··· 115 115 .mcgrps = psample_nl_mcgrps, 116 116 .small_ops = psample_nl_ops, 117 117 .n_small_ops = ARRAY_SIZE(psample_nl_ops), 118 + .resv_start_op = PSAMPLE_CMD_GET_GROUP + 1, 118 119 .n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps), 119 120 }; 120 121
+2 -1
net/smc/smc_netlink.c
··· 142 142 .netnsok = true, 143 143 .module = THIS_MODULE, 144 144 .ops = smc_gen_nl_ops, 145 - .n_ops = ARRAY_SIZE(smc_gen_nl_ops) 145 + .n_ops = ARRAY_SIZE(smc_gen_nl_ops), 146 + .resv_start_op = SMC_NETLINK_DISABLE_HS_LIMITATION + 1, 146 147 }; 147 148 148 149 int __init smc_nl_init(void)
+2 -1
net/smc/smc_pnet.c
··· 715 715 .netnsok = true, 716 716 .module = THIS_MODULE, 717 717 .ops = smc_pnet_ops, 718 - .n_ops = ARRAY_SIZE(smc_pnet_ops) 718 + .n_ops = ARRAY_SIZE(smc_pnet_ops), 719 + .resv_start_op = SMC_PNETID_FLUSH + 1, 719 720 }; 720 721 721 722 bool smc_pnet_is_ndev_pnetid(struct net *net, u8 *pnetid)
+1
net/tipc/netlink.c
··· 294 294 .module = THIS_MODULE, 295 295 .ops = tipc_genl_v2_ops, 296 296 .n_ops = ARRAY_SIZE(tipc_genl_v2_ops), 297 + .resv_start_op = TIPC_NL_ADDR_LEGACY_GET + 1, 297 298 }; 298 299 299 300 int __init tipc_netlink_start(void)
+1
net/wireless/nl80211.c
··· 17237 17237 .n_ops = ARRAY_SIZE(nl80211_ops), 17238 17238 .small_ops = nl80211_small_ops, 17239 17239 .n_small_ops = ARRAY_SIZE(nl80211_small_ops), 17240 + .resv_start_op = NL80211_CMD_REMOVE_LINK_STA + 1, 17240 17241 .mcgrps = nl80211_mcgrps, 17241 17242 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps), 17242 17243 .parallel_ops = true,