size_t                  priv_size;
        void                    (*setup)(struct net_device *dev);
 
-       int                     maxtype;
+       unsigned int            maxtype;
        const struct nla_policy *policy;
        int                     (*validate)(struct nlattr *tb[],
                                            struct nlattr *data[],
        unsigned int            (*get_num_tx_queues)(void);
        unsigned int            (*get_num_rx_queues)(void);
 
-       int                     slave_maxtype;
+       unsigned int            slave_maxtype;
        const struct nla_policy *slave_policy;
        int                     (*slave_changelink)(struct net_device *dev,
                                                    struct net_device *slave_dev,
 
 #include <net/rtnetlink.h>
 #include <net/net_namespace.h>
 
+#define RTNL_MAX_TYPE          48
+#define RTNL_SLAVE_MAX_TYPE    36
+
 struct rtnl_link {
        rtnl_doit_func          doit;
        rtnl_dumpit_func        dumpit;
 {
        int err;
 
+       /* Sanity-check max sizes to avoid stack buffer overflow. */
+       if (WARN_ON(ops->maxtype > RTNL_MAX_TYPE ||
+                   ops->slave_maxtype > RTNL_SLAVE_MAX_TYPE))
+               return -EINVAL;
+
        rtnl_lock();
        err = __rtnl_link_register(ops);
        rtnl_unlock();
        }
 
        if (1) {
-               struct nlattr *attr[ops ? ops->maxtype + 1 : 1];
-               struct nlattr *slave_attr[m_ops ? m_ops->slave_maxtype + 1 : 1];
+               struct nlattr *attr[RTNL_MAX_TYPE + 1];
+               struct nlattr *slave_attr[RTNL_SLAVE_MAX_TYPE + 1];
                struct nlattr **data = NULL;
                struct nlattr **slave_data = NULL;
                struct net *dest_net, *link_net = NULL;
 
                if (ops) {
+                       if (ops->maxtype > RTNL_MAX_TYPE)
+                               return -EINVAL;
+
                        if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
                                err = nla_parse_nested(attr, ops->maxtype,
                                                       linkinfo[IFLA_INFO_DATA],
                }
 
                if (m_ops) {
+                       if (ops->slave_maxtype > RTNL_SLAVE_MAX_TYPE)
+                               return -EINVAL;
+
                        if (m_ops->slave_maxtype &&
                            linkinfo[IFLA_INFO_SLAVE_DATA]) {
                                err = nla_parse_nested(slave_attr,