mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
Merge branch 'netdev-name'
Cong Wang says: ==================== net: forbid net devices named "all" "default" or "config" /proc/sys/net/ipv[46]/conf/<dev> could conflict with /proc/sys/net/ipv[46]/conf/(all|default). And /proc/net/vlan/<dev> could conflict with /proc/net/vlan/config. Besides kernel warnings, undefined behavior such as duplicated proc files also appears, therefore we should forbid these names. v2: introduce a helper function, suggested by Florian fix error handling for ipv6_add_dev() in addrconf_init() ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
772e7023e6
@ -216,6 +216,12 @@ static inline int inet_is_local_reserved_port(struct net *net, int port)
|
||||
return 0;
|
||||
return test_bit(port, net->ipv4.sysctl_local_reserved_ports);
|
||||
}
|
||||
|
||||
static inline bool sysctl_dev_name_is_allowed(const char *name)
|
||||
{
|
||||
return strcmp(name, "default") != 0 && strcmp(name, "all") != 0;
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int inet_is_local_reserved_port(struct net *net, int port)
|
||||
{
|
||||
|
@ -325,23 +325,24 @@ static void vlan_transfer_features(struct net_device *dev,
|
||||
netdev_update_features(vlandev);
|
||||
}
|
||||
|
||||
static void __vlan_device_event(struct net_device *dev, unsigned long event)
|
||||
static int __vlan_device_event(struct net_device *dev, unsigned long event)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_CHANGENAME:
|
||||
vlan_proc_rem_dev(dev);
|
||||
if (vlan_proc_add_dev(dev) < 0)
|
||||
pr_warn("failed to change proc name for %s\n",
|
||||
dev->name);
|
||||
err = vlan_proc_add_dev(dev);
|
||||
break;
|
||||
case NETDEV_REGISTER:
|
||||
if (vlan_proc_add_dev(dev) < 0)
|
||||
pr_warn("failed to add proc entry for %s\n", dev->name);
|
||||
err = vlan_proc_add_dev(dev);
|
||||
break;
|
||||
case NETDEV_UNREGISTER:
|
||||
vlan_proc_rem_dev(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int vlan_device_event(struct notifier_block *unused, unsigned long event,
|
||||
@ -356,8 +357,12 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
|
||||
bool last = false;
|
||||
LIST_HEAD(list);
|
||||
|
||||
if (is_vlan_dev(dev))
|
||||
__vlan_device_event(dev, event);
|
||||
if (is_vlan_dev(dev)) {
|
||||
int err = __vlan_device_event(dev, event);
|
||||
|
||||
if (err)
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
if ((event == NETDEV_UP) &&
|
||||
(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
|
||||
|
@ -171,6 +171,8 @@ int vlan_proc_add_dev(struct net_device *vlandev)
|
||||
struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
|
||||
struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id);
|
||||
|
||||
if (!strcmp(vlandev->name, name_conf))
|
||||
return -EINVAL;
|
||||
vlan->dent =
|
||||
proc_create_data(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR,
|
||||
vn->proc_vlan_dir, &vlandev_fops, vlandev);
|
||||
|
@ -180,11 +180,12 @@ static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
|
||||
static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
|
||||
int destroy);
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static void devinet_sysctl_register(struct in_device *idev);
|
||||
static int devinet_sysctl_register(struct in_device *idev);
|
||||
static void devinet_sysctl_unregister(struct in_device *idev);
|
||||
#else
|
||||
static void devinet_sysctl_register(struct in_device *idev)
|
||||
static int devinet_sysctl_register(struct in_device *idev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static void devinet_sysctl_unregister(struct in_device *idev)
|
||||
{
|
||||
@ -232,6 +233,7 @@ EXPORT_SYMBOL(in_dev_finish_destroy);
|
||||
static struct in_device *inetdev_init(struct net_device *dev)
|
||||
{
|
||||
struct in_device *in_dev;
|
||||
int err = -ENOMEM;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
@ -252,7 +254,13 @@ static struct in_device *inetdev_init(struct net_device *dev)
|
||||
/* Account for reference dev->ip_ptr (below) */
|
||||
in_dev_hold(in_dev);
|
||||
|
||||
devinet_sysctl_register(in_dev);
|
||||
err = devinet_sysctl_register(in_dev);
|
||||
if (err) {
|
||||
in_dev->dead = 1;
|
||||
in_dev_put(in_dev);
|
||||
in_dev = NULL;
|
||||
goto out;
|
||||
}
|
||||
ip_mc_init_dev(in_dev);
|
||||
if (dev->flags & IFF_UP)
|
||||
ip_mc_up(in_dev);
|
||||
@ -260,7 +268,7 @@ static struct in_device *inetdev_init(struct net_device *dev)
|
||||
/* we can receive as soon as ip_ptr is set -- do this last */
|
||||
rcu_assign_pointer(dev->ip_ptr, in_dev);
|
||||
out:
|
||||
return in_dev;
|
||||
return in_dev ?: ERR_PTR(err);
|
||||
out_kfree:
|
||||
kfree(in_dev);
|
||||
in_dev = NULL;
|
||||
@ -1347,8 +1355,8 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
|
||||
if (!in_dev) {
|
||||
if (event == NETDEV_REGISTER) {
|
||||
in_dev = inetdev_init(dev);
|
||||
if (!in_dev)
|
||||
return notifier_from_errno(-ENOMEM);
|
||||
if (IS_ERR(in_dev))
|
||||
return notifier_from_errno(PTR_ERR(in_dev));
|
||||
if (dev->flags & IFF_LOOPBACK) {
|
||||
IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
|
||||
IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
|
||||
@ -2182,11 +2190,21 @@ static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
static void devinet_sysctl_register(struct in_device *idev)
|
||||
static int devinet_sysctl_register(struct in_device *idev)
|
||||
{
|
||||
neigh_sysctl_register(idev->dev, idev->arp_parms, NULL);
|
||||
__devinet_sysctl_register(dev_net(idev->dev), idev->dev->name,
|
||||
int err;
|
||||
|
||||
if (!sysctl_dev_name_is_allowed(idev->dev->name))
|
||||
return -EINVAL;
|
||||
|
||||
err = neigh_sysctl_register(idev->dev, idev->arp_parms, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
err = __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name,
|
||||
&idev->cnf);
|
||||
if (err)
|
||||
neigh_sysctl_unregister(idev->arp_parms);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void devinet_sysctl_unregister(struct in_device *idev)
|
||||
|
@ -108,11 +108,12 @@ static inline u32 cstamp_delta(unsigned long cstamp)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static void addrconf_sysctl_register(struct inet6_dev *idev);
|
||||
static int addrconf_sysctl_register(struct inet6_dev *idev);
|
||||
static void addrconf_sysctl_unregister(struct inet6_dev *idev);
|
||||
#else
|
||||
static inline void addrconf_sysctl_register(struct inet6_dev *idev)
|
||||
static inline int addrconf_sysctl_register(struct inet6_dev *idev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void addrconf_sysctl_unregister(struct inet6_dev *idev)
|
||||
@ -310,16 +311,16 @@ static int snmp6_alloc_dev(struct inet6_dev *idev)
|
||||
static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
|
||||
{
|
||||
struct inet6_dev *ndev;
|
||||
int err = -ENOMEM;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (dev->mtu < IPV6_MIN_MTU)
|
||||
return NULL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
ndev = kzalloc(sizeof(struct inet6_dev), GFP_KERNEL);
|
||||
|
||||
if (ndev == NULL)
|
||||
return NULL;
|
||||
return ERR_PTR(err);
|
||||
|
||||
rwlock_init(&ndev->lock);
|
||||
ndev->dev = dev;
|
||||
@ -332,7 +333,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
|
||||
ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
|
||||
if (ndev->nd_parms == NULL) {
|
||||
kfree(ndev);
|
||||
return NULL;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
if (ndev->cnf.forwarding)
|
||||
dev_disable_lro(dev);
|
||||
@ -346,17 +347,14 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
|
||||
neigh_parms_release(&nd_tbl, ndev->nd_parms);
|
||||
dev_put(dev);
|
||||
kfree(ndev);
|
||||
return NULL;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
if (snmp6_register_dev(ndev) < 0) {
|
||||
ADBG(KERN_WARNING
|
||||
"%s: cannot create /proc/net/dev_snmp6/%s\n",
|
||||
__func__, dev->name);
|
||||
neigh_parms_release(&nd_tbl, ndev->nd_parms);
|
||||
ndev->dead = 1;
|
||||
in6_dev_finish_destroy(ndev);
|
||||
return NULL;
|
||||
goto err_release;
|
||||
}
|
||||
|
||||
/* One reference from device. We must do this before
|
||||
@ -394,7 +392,12 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
|
||||
|
||||
ipv6_mc_init_dev(ndev);
|
||||
ndev->tstamp = jiffies;
|
||||
addrconf_sysctl_register(ndev);
|
||||
err = addrconf_sysctl_register(ndev);
|
||||
if (err) {
|
||||
ipv6_mc_destroy_dev(ndev);
|
||||
del_timer(&ndev->regen_timer);
|
||||
goto err_release;
|
||||
}
|
||||
/* protected by rtnl_lock */
|
||||
rcu_assign_pointer(dev->ip6_ptr, ndev);
|
||||
|
||||
@ -409,6 +412,12 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
|
||||
ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
|
||||
|
||||
return ndev;
|
||||
|
||||
err_release:
|
||||
neigh_parms_release(&nd_tbl, ndev->nd_parms);
|
||||
ndev->dead = 1;
|
||||
in6_dev_finish_destroy(ndev);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static struct inet6_dev *ipv6_find_idev(struct net_device *dev)
|
||||
@ -420,7 +429,7 @@ static struct inet6_dev *ipv6_find_idev(struct net_device *dev)
|
||||
idev = __in6_dev_get(dev);
|
||||
if (!idev) {
|
||||
idev = ipv6_add_dev(dev);
|
||||
if (!idev)
|
||||
if (IS_ERR(idev))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2830,8 +2839,8 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
|
||||
case NETDEV_REGISTER:
|
||||
if (!idev && dev->mtu >= IPV6_MIN_MTU) {
|
||||
idev = ipv6_add_dev(dev);
|
||||
if (!idev)
|
||||
return notifier_from_errno(-ENOMEM);
|
||||
if (IS_ERR(idev))
|
||||
return notifier_from_errno(PTR_ERR(idev));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2851,7 +2860,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
|
||||
if (!idev && dev->mtu >= IPV6_MIN_MTU)
|
||||
idev = ipv6_add_dev(dev);
|
||||
|
||||
if (idev) {
|
||||
if (!IS_ERR_OR_NULL(idev)) {
|
||||
idev->if_flags |= IF_READY;
|
||||
run_pending = 1;
|
||||
}
|
||||
@ -2894,7 +2903,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
|
||||
break;
|
||||
}
|
||||
|
||||
if (idev) {
|
||||
if (!IS_ERR_OR_NULL(idev)) {
|
||||
if (run_pending)
|
||||
addrconf_dad_run(idev);
|
||||
|
||||
@ -2929,7 +2938,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
|
||||
|
||||
if (!idev && dev->mtu >= IPV6_MIN_MTU) {
|
||||
idev = ipv6_add_dev(dev);
|
||||
if (idev)
|
||||
if (!IS_ERR(idev))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2950,10 +2959,14 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
|
||||
if (idev) {
|
||||
snmp6_unregister_dev(idev);
|
||||
addrconf_sysctl_unregister(idev);
|
||||
addrconf_sysctl_register(idev);
|
||||
err = snmp6_register_dev(idev);
|
||||
err = addrconf_sysctl_register(idev);
|
||||
if (err)
|
||||
return notifier_from_errno(err);
|
||||
err = snmp6_register_dev(idev);
|
||||
if (err) {
|
||||
addrconf_sysctl_unregister(idev);
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -5248,12 +5261,23 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
static void addrconf_sysctl_register(struct inet6_dev *idev)
|
||||
static int addrconf_sysctl_register(struct inet6_dev *idev)
|
||||
{
|
||||
neigh_sysctl_register(idev->dev, idev->nd_parms,
|
||||
&ndisc_ifinfo_sysctl_change);
|
||||
__addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name,
|
||||
idev, &idev->cnf);
|
||||
int err;
|
||||
|
||||
if (!sysctl_dev_name_is_allowed(idev->dev->name))
|
||||
return -EINVAL;
|
||||
|
||||
err = neigh_sysctl_register(idev->dev, idev->nd_parms,
|
||||
&ndisc_ifinfo_sysctl_change);
|
||||
if (err)
|
||||
return err;
|
||||
err = __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name,
|
||||
idev, &idev->cnf);
|
||||
if (err)
|
||||
neigh_sysctl_unregister(idev->nd_parms);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void addrconf_sysctl_unregister(struct inet6_dev *idev)
|
||||
@ -5338,6 +5362,7 @@ static struct rtnl_af_ops inet6_ops = {
|
||||
|
||||
int __init addrconf_init(void)
|
||||
{
|
||||
struct inet6_dev *idev;
|
||||
int i, err;
|
||||
|
||||
err = ipv6_addr_label_init();
|
||||
@ -5376,11 +5401,12 @@ int __init addrconf_init(void)
|
||||
* device and it being up should be removed.
|
||||
*/
|
||||
rtnl_lock();
|
||||
if (!ipv6_add_dev(init_net.loopback_dev))
|
||||
err = -ENOMEM;
|
||||
idev = ipv6_add_dev(init_net.loopback_dev);
|
||||
rtnl_unlock();
|
||||
if (err)
|
||||
if (IS_ERR(idev)) {
|
||||
err = PTR_ERR(idev);
|
||||
goto errlo;
|
||||
}
|
||||
|
||||
for (i = 0; i < IN6_ADDR_HSIZE; i++)
|
||||
INIT_HLIST_HEAD(&inet6_addr_lst[i]);
|
||||
|
Loading…
Reference in New Issue
Block a user