@@ -664,6 +664,12 @@ int device_set_ifname(struct device *dev, const char *name)
if (!strcmp(dev->ifname, name))
return 0;
+ if (strnlen(name, IFNAMSIZ) >= IFNAMSIZ) {
+ netifd_log_message(L_WARNING, "Interface name '%s' too long\n",
+ name);
+ return ENAMETOOLONG;
+ }
+
if (dev->avl.key)
avl_delete(&devices, &dev->avl);
@@ -61,13 +61,23 @@ static int vlan_set_device_state(struct device *dev, bool up)
return ret;
}
-static void vlan_dev_set_name(struct vlan_device *vldev, struct device *dev)
+static int vlan_dev_set_name(struct vlan_device *vldev, struct device *dev)
{
- char name[IFNAMSIZ];
+ int ret = 0;
+
+ /* allow for adding dot + VLAN id */
+ char name[IFNAMSIZ + 6];
vldev->dev.hidden = dev->hidden;
- snprintf(name, IFNAMSIZ, "%s.%d", dev->ifname, vldev->id);
- device_set_ifname(&vldev->dev, name);
+ /* Truncate dev->ifname so that adding dot + VLAN id + '\0' doesn't exceed IFNAMSIZ */
+ snprintf(name, sizeof(name), "%.*s.%d", IFNAMSIZ, dev->ifname, vldev->id & 0xfff);
+ if (strnlen(name, IFNAMSIZ) >= IFNAMSIZ) {
+ netifd_log_message(L_WARNING, "VLAN interface name '%s' too long", name);
+ ret = ENAMETOOLONG;
+ } else {
+ device_set_ifname(&vldev->dev, name);
+ }
+ return ret;
}
static void vlan_dev_cb(struct device_user *dep, enum device_event ev)
@@ -129,7 +139,9 @@ static struct device *get_vlan_device(struct device *dev, int id, bool create)
device_init(&vldev->dev, &vlan_type, NULL);
- vlan_dev_set_name(vldev, dev);
+ if (vlan_dev_set_name(vldev, dev))
+ return NULL;
+
vldev->dev.default_config = true;
vldev->set_state = vldev->dev.set_state;