]> git.proxmox.com Git - mirror_lxc.git/commitdiff
network: use static memory for net device names
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 31 Aug 2017 22:23:30 +0000 (00:23 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 1 Sep 2017 10:32:56 +0000 (12:32 +0200)
All network devices can only be of size < IFNAMSIZ. So let's spare the useless
heap allocations and use static memory.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/confile.c
src/lxc/confile_legacy.c
src/lxc/confile_utils.c
src/lxc/confile_utils.h
src/lxc/criu.c
src/lxc/network.c
src/lxc/network.h
src/lxc/start.c

index e66bae314ed886089ac083f61d722a34c6c3d88c..625616c69e66675233c7b5f50bd46be9685a809a 100644 (file)
@@ -483,7 +483,7 @@ static int set_config_net_link(const char *key, const char *value,
        if (value[strlen(value) - 1] == '+' && netdev->type == LXC_NET_PHYS)
                ret = create_matched_ifnames(value, lxc_conf, netdev);
        else
-               ret = network_ifname(&netdev->link, value);
+               ret = network_ifname(netdev->link, value);
 
        return ret;
 }
@@ -503,7 +503,7 @@ static int set_config_net_name(const char *key, const char *value,
        if (!netdev)
                return -1;
 
-       return network_ifname(&netdev->name, value);
+       return network_ifname(netdev->name, value);
 }
 
 static int set_config_net_veth_pair(const char *key, const char *value,
@@ -521,7 +521,7 @@ static int set_config_net_veth_pair(const char *key, const char *value,
        if (!netdev)
                return -1;
 
-       return network_ifname(&netdev->priv.veth_attr.pair, value);
+       return network_ifname(netdev->priv.veth_attr.pair, value);
 }
 
 static int set_config_net_macvlan_mode(const char *key, const char *value,
@@ -3690,8 +3690,7 @@ static int clr_config_net_name(const char *key, struct lxc_conf *lxc_conf,
        if (!netdev)
                return -1;
 
-       free(netdev->name);
-       netdev->name = NULL;
+       netdev->name[0] = '\0';
 
        return 0;
 }
@@ -3725,8 +3724,7 @@ static int clr_config_net_link(const char *key, struct lxc_conf *lxc_conf,
        if (!netdev)
                return -1;
 
-       free(netdev->link);
-       netdev->link = NULL;
+       netdev->link[0] = '\0';
 
        return 0;
 }
@@ -3763,8 +3761,7 @@ static int clr_config_net_veth_pair(const char *key, struct lxc_conf *lxc_conf,
        if (!netdev)
                return -1;
 
-       free(netdev->priv.veth_attr.pair);
-       netdev->priv.veth_attr.pair = NULL;
+       netdev->priv.veth_attr.pair[0] = '\0';
 
        return 0;
 }
@@ -4032,7 +4029,7 @@ static int get_config_net_link(const char *key, char *retv, int inlen,
        if (!netdev)
                return -1;
 
-       if (netdev->link)
+       if (netdev->link[0] != '\0')
                strprint(retv, inlen, "%s", netdev->link);
 
        return fulllen;
@@ -4056,7 +4053,7 @@ static int get_config_net_name(const char *key, char *retv, int inlen,
        if (!netdev)
                return -1;
 
-       if (netdev->name)
+       if (netdev->name[0] != '\0')
                strprint(retv, inlen, "%s", netdev->name);
 
        return fulllen;
@@ -4129,8 +4126,9 @@ static int get_config_net_veth_pair(const char *key, char *retv, int inlen,
                return 0;
 
        strprint(retv, inlen, "%s",
-                netdev->priv.veth_attr.pair ? netdev->priv.veth_attr.pair
-                                            : netdev->priv.veth_attr.veth1);
+                netdev->priv.veth_attr.pair[0] != '\0'
+                    ? netdev->priv.veth_attr.pair
+                    : netdev->priv.veth_attr.veth1);
 
        return fulllen;
 }
index f3bd8fbaf12ac4a9ff4654245498f9599886b0d7..80dd3851e728b8efc77be01e8b4d76eef77debf5 100644 (file)
@@ -110,10 +110,6 @@ static void lxc_remove_nic(struct lxc_list *it)
 
        lxc_list_del(it);
 
-       free(netdev->link);
-       free(netdev->name);
-       if (netdev->type == LXC_NET_VETH)
-               free(netdev->priv.veth_attr.pair);
        free(netdev->upscript);
        free(netdev->downscript);
        free(netdev->hwaddr);
@@ -174,6 +170,16 @@ int set_config_network_legacy_type(const char *key, const char *value,
        lxc_list_init(&netdev->ipv4);
        lxc_list_init(&netdev->ipv6);
 
+       netdev->name[0] = '\0';
+       netdev->link[0] = '\0';
+       memset(&netdev->priv, 0, sizeof(netdev->priv));
+       /* I'm not completely sure if the memset takes care to zero the arrays
+        * in the union as well. So let's make extra sure and set the first byte
+        * to zero so that we don't have any surprises.
+        */
+       netdev->priv.veth_attr.pair[0] = '\0';
+       netdev->priv.veth_attr.veth1[0] = '\0';
+
        list = malloc(sizeof(*list));
        if (!list) {
                SYSERROR("failed to allocate memory");
@@ -423,7 +429,7 @@ int set_config_network_legacy_link(const char *key, const char *value,
                free(it);
                ret = create_matched_ifnames(value, lxc_conf, NULL);
        } else {
-               ret = network_ifname(&netdev->link, value);
+               ret = network_ifname(netdev->link, value);
        }
 
        return ret;
@@ -438,7 +444,7 @@ int set_config_network_legacy_name(const char *key, const char *value,
        if (!netdev)
                return -1;
 
-       return network_ifname(&netdev->name, value);
+       return network_ifname(netdev->name, value);
 }
 
 int set_config_network_legacy_veth_pair(const char *key, const char *value,
@@ -455,7 +461,7 @@ int set_config_network_legacy_veth_pair(const char *key, const char *value,
                return -1;
        }
 
-       return network_ifname(&netdev->priv.veth_attr.pair, value);
+       return network_ifname(netdev->priv.veth_attr.pair, value);
 }
 
 int set_config_network_legacy_macvlan_mode(const char *key, const char *value,
@@ -848,12 +854,12 @@ int get_config_network_legacy_item(const char *key, char *retv, int inlen,
        if (!netdev)
                return -1;
        if (strcmp(p1, "name") == 0) {
-               if (netdev->name)
+               if (netdev->name[0] != '\0')
                        strprint(retv, inlen, "%s", netdev->name);
        } else if (strcmp(p1, "type") == 0) {
                strprint(retv, inlen, "%s", lxc_net_type_to_str(netdev->type));
        } else if (strcmp(p1, "link") == 0) {
-               if (netdev->link)
+               if (netdev->link[0] != '\0')
                        strprint(retv, inlen, "%s", netdev->link);
        } else if (strcmp(p1, "flags") == 0) {
                if (netdev->flags & IFF_UP)
@@ -895,7 +901,7 @@ int get_config_network_legacy_item(const char *key, char *retv, int inlen,
        } else if (strcmp(p1, "veth.pair") == 0) {
                if (netdev->type == LXC_NET_VETH) {
                        strprint(retv, inlen, "%s",
-                                netdev->priv.veth_attr.pair
+                                netdev->priv.veth_attr.pair[0] != '\0'
                                     ? netdev->priv.veth_attr.pair
                                     : netdev->priv.veth_attr.veth1);
                }
index ba4b9c0ddb298ca4372f2596be03322ea4250241..b3ae08b6826ef493167d569f4277328aaceae25e 100644 (file)
@@ -183,6 +183,15 @@ struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail
        memset(netdev, 0, sizeof(*netdev));
        lxc_list_init(&netdev->ipv4);
        lxc_list_init(&netdev->ipv6);
+       netdev->name[0] = '\0';
+       netdev->link[0] = '\0';
+       memset(&netdev->priv, 0, sizeof(netdev->priv));
+       /* I'm not completely sure if the memset takes care to zero the arrays
+        * in the union as well. So let's make extra sure and set the first byte
+        * to zero so that we don't have any surprises.
+        */
+       netdev->priv.veth_attr.pair[0] = '\0';
+       netdev->priv.veth_attr.veth1[0] = '\0';
 
        /* give network a unique index */
        netdev->idx = idx;
@@ -258,7 +267,7 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
                switch (netdev->type) {
                case LXC_NET_VETH:
                        TRACE("type: veth");
-                       if (netdev->priv.veth_attr.pair)
+                       if (netdev->priv.veth_attr.pair[0] != '\0')
                                TRACE("veth pair: %s",
                                      netdev->priv.veth_attr.pair);
                        if (netdev->priv.veth_attr.veth1[0] != '\0')
@@ -300,9 +309,9 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
                if (netdev->type != LXC_NET_EMPTY) {
                        TRACE("flags: %s",
                              netdev->flags == IFF_UP ? "up" : "none");
-                       if (netdev->link)
+                       if (netdev->link[0] != '\0')
                                TRACE("link: %s", netdev->link);
-                       if (netdev->name)
+                       if (netdev->name[0] != '\0')
                                TRACE("name: %s", netdev->name);
                        if (netdev->hwaddr)
                                TRACE("hwaddr: %s", netdev->hwaddr);
@@ -350,10 +359,6 @@ static void lxc_free_netdev(struct lxc_netdev *netdev)
 {
        struct lxc_list *cur, *next;
 
-       free(netdev->link);
-       free(netdev->name);
-       if (netdev->type == LXC_NET_VETH)
-               free(netdev->priv.veth_attr.pair);
        free(netdev->upscript);
        free(netdev->downscript);
        free(netdev->hwaddr);
@@ -503,9 +508,15 @@ int config_ip_prefix(struct in_addr *addr)
        return 0;
 }
 
-int network_ifname(char **valuep, const char *value)
+int network_ifname(char *valuep, const char *value)
 {
-       return set_config_string_item_max(valuep, value, IFNAMSIZ);
+       if (strlen(value) >= IFNAMSIZ) {
+               ERROR("Network devie name \"%s\" is too long (>= %zu)", value,
+                     (size_t)IFNAMSIZ);
+       }
+
+       strcpy(valuep, value);
+       return 0;
 }
 
 int rand_complete_hwaddr(char *hwaddr)
index 222de3de9fb064cd54d9e27dda687d321183879c..2f1079a2c3c31c9e224700ca7594c449315efa56 100644 (file)
@@ -77,7 +77,7 @@ extern int set_config_string_item_max(char **conf_item, const char *value,
                                      size_t max);
 extern int set_config_path_item(char **conf_item, const char *value);
 extern int config_ip_prefix(struct in_addr *addr);
-extern int network_ifname(char **valuep, const char *value);
+extern int network_ifname(char *valuep, const char *value);
 extern int rand_complete_hwaddr(char *hwaddr);
 extern bool lxc_config_net_hwaddr(const char *line);
 extern void update_hwaddr(const char *line);
index 62a0eb7d6dc3a4725a4a89b273fe27ea8c8d3b19..2f444ec440593e7d5349a0b43e6dc9c19c1291e8 100644 (file)
@@ -524,7 +524,7 @@ static void exec_criu(struct criu_opts *opts)
                        case LXC_NET_VETH:
                                veth = n->priv.veth_attr.pair;
 
-                               if (n->link) {
+                               if (n->link[0] != '\0') {
                                        if (external_not_veth)
                                                fmt = "veth[%s]:%s@%s";
                                        else
@@ -543,7 +543,7 @@ static void exec_criu(struct criu_opts *opts)
                                        goto err;
                                break;
                        case LXC_NET_MACVLAN:
-                               if (!n->link) {
+                               if (n->link[0] == '\0') {
                                        ERROR("no host interface for macvlan %s", n->name);
                                        goto err;
                                }
@@ -765,11 +765,17 @@ static bool restore_net_info(struct lxc_container *c)
 
                snprintf(template, sizeof(template), "vethXXXXXX");
 
-               if (!netdev->priv.veth_attr.pair)
-                       netdev->priv.veth_attr.pair = lxc_mkifname(template);
+               if (netdev->priv.veth_attr.pair[0] == '\0' &&
+                   netdev->priv.veth_attr.veth1[0] == '\0') {
+                       char *tmp;
 
-               if (!netdev->priv.veth_attr.pair)
-                       goto out_unlock;
+                       tmp = lxc_mkifname(template);
+                       if (!tmp)
+                               goto out_unlock;
+
+                       strcpy(netdev->priv.veth_attr.veth1, tmp);
+                       free(tmp);
+               }
        }
 
        has_error = false;
index f10dd3f3e1ea89ae1937d1f583988c114cf3c71f..07a4360aca5bce57a6e5550dc528440fb7a60463 100644 (file)
@@ -101,7 +101,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
        char veth1buf[IFNAMSIZ], veth2buf[IFNAMSIZ];
        unsigned int mtu = 0;
 
-       if (netdev->priv.veth_attr.pair) {
+       if (netdev->priv.veth_attr.pair[0] != '\0') {
                veth1 = netdev->priv.veth_attr.pair;
                if (handler->conf->reboot)
                        lxc_netdev_delete_by_name(veth1);
@@ -163,7 +163,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
                        WARN("Failed to parse mtu");
                else
                        INFO("Retrieved mtu %d", mtu);
-       } else if (netdev->link) {
+       } else if (netdev->link[0] != '\0') {
                bridge_index = if_nametoindex(netdev->link);
                if (bridge_index) {
                        mtu = netdev_get_mtu(bridge_index);
@@ -186,7 +186,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
                }
        }
 
-       if (netdev->link) {
+       if (netdev->link[0] != '\0') {
                err = lxc_bridge_attach(netdev->link, veth1);
                if (err) {
                        ERROR("Failed to attach \"%s\" to bridge \"%s\": %s",
@@ -217,7 +217,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
 out_delete:
        if (netdev->ifindex != 0)
                lxc_netdev_delete_by_name(veth1);
-       if (!netdev->priv.veth_attr.pair)
+       if (netdev->priv.veth_attr.pair != veth1)
                free(veth1);
        free(veth2);
        return -1;
@@ -228,7 +228,7 @@ static int instantiate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n
        char peerbuf[IFNAMSIZ], *peer;
        int err;
 
-       if (!netdev->link) {
+       if (netdev->link[0] == '\0') {
                ERROR("No link for macvlan network device specified");
                return -1;
        }
@@ -279,7 +279,7 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
        static uint16_t vlan_cntr = 0;
        unsigned int mtu = 0;
 
-       if (!netdev->link) {
+       if (netdev->link[0] == '\0') {
                ERROR("No link for vlan network device specified");
                return -1;
        }
@@ -308,7 +308,7 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
                if (lxc_safe_uint(netdev->mtu, &mtu) < 0) {
                        ERROR("Failed to retrieve mtu from \"%d\"/\"%s\".",
                              netdev->ifindex,
-                             netdev->name ? netdev->name : "(null)");
+                             netdev->name[0] != '\0' ? netdev->name : "(null)");
                        return -1;
                }
                err = lxc_netdev_set_mtu(peer, mtu);
@@ -325,7 +325,7 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
 
 static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netdev)
 {
-       if (!netdev->link) {
+       if (netdev->link[0] == '\0') {
                ERROR("No link for physical interface specified");
                return -1;
        }
@@ -380,7 +380,7 @@ static int shutdown_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
        char *veth1;
        int err;
 
-       if (netdev->priv.veth_attr.pair)
+       if (netdev->priv.veth_attr.pair[0] != '\0')
                veth1 = netdev->priv.veth_attr.pair;
        else
                veth1 = netdev->priv.veth_attr.veth1;
@@ -2014,7 +2014,7 @@ int lxc_find_gateway_addresses(struct lxc_handler *handler)
                        return -1;
                }
 
-               if (!netdev->link) {
+               if (netdev->link[0] == '\0') {
                        ERROR("Automatic gateway detection needs a link interface");
                        return -1;
                }
@@ -2088,7 +2088,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, char *lxcname,
                        exit(EXIT_FAILURE);
                }
 
-               if (netdev->link)
+               if (netdev->link[0] != '\0')
                        strncpy(netdev_link, netdev->link, IFNAMSIZ);
                else
                        strncpy(netdev_link, "none", IFNAMSIZ);
@@ -2100,8 +2100,8 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, char *lxcname,
 
                INFO("Execing lxc-user-nic create %s %s %s veth %s %s", lxcpath,
                     lxcname, pidstr, netdev_link,
-                    netdev->name ? netdev->name : "(null)");
-               if (netdev->name)
+                    netdev->name[0] != '\0' ? netdev->name : "(null)");
+               if (netdev->name[0] != '\0')
                        execlp(LXC_USERNIC_PATH, LXC_USERNIC_PATH, "create",
                               lxcpath, lxcname, pidstr, "veth", netdev_link,
                               netdev->name, (char *)NULL);
@@ -2140,11 +2140,6 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, char *lxcname,
                return -1;
        }
 
-       netdev->name = malloc(IFNAMSIZ + 1);
-       if (!netdev->name) {
-               SYSERROR("Failed to allocate memory");
-               return -1;
-       }
        memset(netdev->name, 0, IFNAMSIZ + 1);
        strncpy(netdev->name, token, IFNAMSIZ);
 
@@ -2240,7 +2235,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, char *lxcname,
                        exit(EXIT_FAILURE);
                }
 
-               if (!netdev->link) {
+               if (netdev->link[0] == '\0') {
                        SYSERROR("Network link for network device \"%s\" is "
                                 "missing", netdev->priv.veth_attr.veth1);
                        exit(EXIT_FAILURE);
@@ -2423,7 +2418,7 @@ int lxc_network_move_created_netdev_priv(const char *lxcpath, char *lxcname,
                }
 
                DEBUG("Moved network device \"%s\"/\"%s\" to network namespace "
-                     "of %d:", ifname, netdev->name ? netdev->name : "(null)",
+                     "of %d:", ifname, netdev->name[0] != '\0' ? netdev->name : "(null)",
                      pid);
        }
 
@@ -2510,18 +2505,18 @@ bool lxc_delete_network_priv(struct lxc_handler *handler)
                        INFO("Interface \"%s\" with index %d already "
                                        "deleted or existing in different network "
                                        "namespace",
-                                       netdev->name ? netdev->name : "(null)",
+                                       netdev->name[0] != '\0' ? netdev->name : "(null)",
                                        netdev->ifindex);
                } else if (ret < 0) {
                        deleted_all = false;
                        WARN("Failed to remove interface \"%s\" with "
                                        "index %d: %s",
-                                       netdev->name ? netdev->name : "(null)",
+                                       netdev->name[0] != '\0' ? netdev->name : "(null)",
                                        netdev->ifindex, strerror(-ret));
                        continue;
                }
                INFO("Removed interface \"%s\" with index %d",
-                               netdev->name ? netdev->name : "(null)",
+                               netdev->name[0] != '\0' ? netdev->name : "(null)",
                                netdev->ifindex);
 
                if (netdev->type != LXC_NET_VETH)
@@ -2530,11 +2525,11 @@ bool lxc_delete_network_priv(struct lxc_handler *handler)
                /* Explicitly delete host veth device to prevent lingering
                 * devices. We had issues in LXD around this.
                 */
-               if (netdev->priv.veth_attr.pair)
+               if (netdev->priv.veth_attr.pair[0] != '\0')
                        hostveth = netdev->priv.veth_attr.pair;
                else
                        hostveth = netdev->priv.veth_attr.veth1;
-               if (*hostveth == '\0')
+               if (hostveth[0] == '\0')
                        continue;
 
                ret = lxc_netdev_delete_by_name(hostveth);
@@ -2767,9 +2762,12 @@ static int lxc_setup_netdev_in_child_namespaces(struct lxc_netdev *netdev)
         * When the IFLA_IFNAME attribute is passed something like "<prefix>%d"
         * netlink will replace the format specifier with an appropriate index.
         */
-       if (!netdev->name)
-               netdev->name = netdev->type == LXC_NET_PHYS ?
-                       netdev->link : "eth%d";
+       if (netdev->name[0] == '\0') {
+               if (netdev->type == LXC_NET_PHYS)
+                       strcpy(netdev->name, netdev->link);
+               else
+                       strcpy(netdev->name, "eth%d");
+       }
 
        /* rename the interface name */
        if (strcmp(ifname, netdev->name) != 0) {
index 17c095802e072764f5c55a998166091824130ff7..b85f9ad29a1195fc6aa5353fe06712c52095bd1b 100644 (file)
@@ -91,7 +91,7 @@ struct lxc_route6 {
  * @ifindex : Ifindex of the network device.
  */
 struct ifla_veth {
-       char *pair;
+       char pair[IFNAMSIZ];
        char veth1[IFNAMSIZ];
        int ifindex;
 };
@@ -151,8 +151,8 @@ struct lxc_netdev {
        int ifindex;
        int type;
        int flags;
-       char *link;
-       char *name;
+       char link[IFNAMSIZ];
+       char name[IFNAMSIZ];
        char *hwaddr;
        char *mtu;
        union netdev_p priv;
index 86d8235529cb2d90f8503184f9881c3f3a2d5c83..c307c5336f56be35a96e5e46fc112eb64f51e46a 100644 (file)
@@ -816,13 +816,6 @@ static int read_unpriv_netifindex(struct lxc_list *network)
                if (netdev->type != LXC_NET_VETH)
                        continue;
 
-               netdev->name = malloc(IFNAMSIZ);
-               if (!netdev->name) {
-                       ERROR("Out of memory.");
-                       close(netpipe);
-                       return -1;
-               }
-
                if (read(netpipe, netdev->name, IFNAMSIZ) != IFNAMSIZ) {
                        close(netpipe);
                        return -1;