diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index 9bc7aa19eb..48527a2c73 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -110,6 +110,8 @@ static int address_new(Network *network, int family, unsigned char prefixlen, Address *address; assert(network); + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(addr); address = new(Address, 1); if (!address) @@ -119,7 +121,7 @@ static int address_new(Network *network, int family, unsigned char prefixlen, .family = family, .prefixlen = prefixlen, .address = *addr, - .peer = *peer, + .peer = peer ? *peer : IN_ADDR_NULL, }; LIST_PREPEND(addresses, network->addresses, address); @@ -146,6 +148,8 @@ static int route_new(Network *network, int family, unsigned char prefixlen, Route *route; assert(network); + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(dest || gateway); route = new(Route, 1); if (!route) @@ -155,7 +159,7 @@ static int route_new(Network *network, int family, unsigned char prefixlen, .family = family, .prefixlen = prefixlen, .dest = dest ? *dest : IN_ADDR_NULL, - .gateway = *gateway, + .gateway = gateway ? *gateway : IN_ADDR_NULL, }; LIST_PREPEND(routes, network->routes, route); @@ -248,6 +252,7 @@ static int netdev_new(Context *context, const char *_kind, const char *_ifname, int r; assert(context); + assert(_kind); if (!ifname_valid(_ifname)) return -EINVAL; @@ -362,6 +367,10 @@ static int network_set_dhcp_type(Context *context, const char *ifname, const cha DHCPType t; int r; + assert(context); + assert(ifname); + assert(dhcp_type); + t = dracut_dhcp_type_from_string(dhcp_type); if (t < 0) return t; @@ -380,6 +389,9 @@ static int network_set_dhcp_type(Context *context, const char *ifname, const cha static int network_set_hostname(Context *context, const char *ifname, const char *hostname) { Network *network; + assert(context); + assert(ifname); + network = network_get(context, ifname); if (!network) return -ENODEV; @@ -387,19 +399,29 @@ static int network_set_hostname(Context *context, const char *ifname, const char return free_and_strdup(&network->hostname, hostname); } -static int network_set_mtu(Context *context, const char *ifname, int family, const char *mtu) { +static int network_set_mtu(Context *context, const char *ifname, const char *mtu) { Network *network; + assert(context); + assert(ifname); + + if (isempty(mtu)) + return 0; + network = network_get(context, ifname); if (!network) return -ENODEV; - return parse_mtu(family, mtu, &network->mtu); + return parse_mtu(AF_UNSPEC, mtu, &network->mtu); } static int network_set_mac_address(Context *context, const char *ifname, const char *mac) { Network *network; + assert(context); + assert(ifname); + assert(mac); + network = network_get(context, ifname); if (!network) return -ENODEV; @@ -411,6 +433,11 @@ static int network_set_address(Context *context, const char *ifname, int family, union in_addr_union *addr, union in_addr_union *peer) { Network *network; + assert(context); + assert(ifname); + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(addr); + if (!in_addr_is_set(family, addr)) return 0; @@ -426,7 +453,12 @@ static int network_set_route(Context *context, const char *ifname, int family, u Network *network; int r; - if (!in_addr_is_set(family, gateway)) + assert(context); + assert(ifname); + assert(IN_SET(family, AF_INET, AF_INET6)); + + if (!(dest && in_addr_is_set(family, dest)) && + !(gateway && in_addr_is_set(family, gateway))) return 0; network = network_get(context, ifname); @@ -439,12 +471,20 @@ static int network_set_route(Context *context, const char *ifname, int family, u return route_new(network, family, prefixlen, dest, gateway, NULL); } -static int network_set_dns(Context *context, const char *ifname, const char *dns) { +static int network_set_dns(Context *context, const char *ifname, int family, const char *dns) { union in_addr_union a; Network *network; - int family, r; + int r; - r = in_addr_from_string_auto(dns, &family, &a); + assert(context); + assert(ifname); + assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6)); + assert(dns); + + if (family == AF_UNSPEC) + r = in_addr_from_string_auto(dns, &family, &a); + else + r = in_addr_from_string(family, dns, &a); if (r < 0) return r; @@ -462,6 +502,9 @@ static int network_set_dhcp_use_dns(Context *context, const char *ifname, bool v Network *network; int r; + assert(context); + assert(ifname); + network = network_get(context, ifname); if (!network) { r = network_new(context, ifname, &network); @@ -478,6 +521,9 @@ static int network_set_vlan(Context *context, const char *ifname, const char *va Network *network; int r; + assert(context); + assert(ifname); + network = network_get(context, ifname); if (!network) { r = network_new(context, ifname, &network); @@ -492,6 +538,9 @@ static int network_set_bridge(Context *context, const char *ifname, const char * Network *network; int r; + assert(context); + assert(ifname); + network = network_get(context, ifname); if (!network) { r = network_new(context, ifname, &network); @@ -506,6 +555,9 @@ static int network_set_bond(Context *context, const char *ifname, const char *va Network *network; int r; + assert(context); + assert(ifname); + network = network_get(context, ifname); if (!network) { r = network_new(context, ifname, &network); @@ -516,10 +568,14 @@ static int network_set_bond(Context *context, const char *ifname, const char *va return free_and_strdup(&network->bond, value); } -static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, int family, const char *value) { +static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, const char *value) { const char *mtu, *p; int r; + assert(context); + assert(ifname); + assert(value); + /* [][:] */ p = strchr(value, ':'); @@ -528,11 +584,9 @@ static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, int fa else mtu = strndupa_safe(value, p - value); - if (!isempty(mtu)) { - r = network_set_mtu(context, ifname, family, mtu); - if (r < 0) - return r; - } + r = network_set_mtu(context, ifname, mtu); + if (r < 0) + return r; if (!p || isempty(p + 1)) return 0; @@ -545,9 +599,15 @@ static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, int fa } static int parse_ip_address_one(int family, const char **value, union in_addr_union *ret) { - const char *p = *value, *q, *buf; + const char *p, *q, *buf; int r; + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(value); + assert(ret); + + p = ASSERT_PTR(*value); + if (p[0] == ':') { *value = p + 1; return 0; @@ -588,6 +648,11 @@ static int parse_netmask_or_prefixlen(int family, const char **value, unsigned c const char *p, *q; int r; + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(value); + assert(*value); + assert(ret); + r = parse_ip_address_one(family, value, &netmask); if (r > 0) { if (family == AF_INET6) @@ -613,23 +678,29 @@ static int parse_netmask_or_prefixlen(int family, const char **value, unsigned c return 0; } -static int parse_ip_dns_address_one(Context *context, const char *ifname, int family, const char **value) { - const char *p = *value, *q, *buf; - int r; +static int parse_ip_dns_address_one(Context *context, const char *ifname, const char **value) { + const char *p, *q, *buf; + int r, family; + + assert(context); + assert(ifname); + assert(value); + + p = ASSERT_PTR(*value); if (isempty(p)) return 0; - if (family == AF_INET6) { - if (p[0] != '[') - return -EINVAL; - + if (p[0] == '[') { q = strchr(p + 1, ']'); if (!q) return -EINVAL; + if (!IN_SET(q[1], ':', '\0')) + return -EINVAL; buf = strndupa_safe(p + 1, q - p - 1); p = q + 1; + family = AF_INET6; } else { q = strchr(p, ':'); if (!q) @@ -638,15 +709,13 @@ static int parse_ip_dns_address_one(Context *context, const char *ifname, int fa buf = strndupa_safe(*value, q - *value); p += strlen(buf); + family = AF_INET; } - r = network_set_dns(context, ifname, buf); + r = network_set_dns(context, ifname, family, buf); if (r < 0) return r; - if (p[0] == ':') - p++; - *value = p; return 0; } @@ -657,6 +726,10 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va unsigned char prefixlen; int r; + assert(context); + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(value); + /* ip=:[]:::::{none|off|dhcp|on|any|dhcp6|auto6|ibft|link6}[:[][:]] * ip=:[]:::::{none|off|dhcp|on|any|dhcp6|auto6|ibft|link6}[:[][:]] */ @@ -723,19 +796,25 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va return 0; /* First, try [][:] */ - r = parse_cmdline_ip_mtu_mac(context, ifname, AF_UNSPEC, p + 1); + r = parse_cmdline_ip_mtu_mac(context, ifname, p + 1); if (r >= 0) return 0; /* Next, try [][:] */ value = p + 1; - r = parse_ip_dns_address_one(context, ifname, family, &value); + r = parse_ip_dns_address_one(context, ifname, &value); if (r < 0) return r; - r = parse_ip_dns_address_one(context, ifname, family, &value); + + value += *value == ':'; + r = parse_ip_dns_address_one(context, ifname, &value); if (r < 0) return r; + /* refuse unexpected trailing strings */ + if (!isempty(value)) + return -EINVAL; + return 0; } @@ -743,6 +822,9 @@ static int parse_cmdline_ip_interface(Context *context, const char *value) { const char *ifname, *dhcp_type, *p; int r; + assert(context); + assert(value); + /* ip=:{dhcp|on|any|dhcp6|auto6|link6}[:[][:]] */ p = strchr(value, ':'); @@ -765,13 +847,16 @@ static int parse_cmdline_ip_interface(Context *context, const char *value) { if (!p) return 0; - return parse_cmdline_ip_mtu_mac(context, ifname, AF_UNSPEC, p + 1); + return parse_cmdline_ip_mtu_mac(context, ifname, p + 1); } static int parse_cmdline_ip(Context *context, const char *key, const char *value) { const char *p; int r; + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return -EINVAL; @@ -796,6 +881,9 @@ static int parse_cmdline_rd_route(Context *context, const char *key, const char const char *buf, *p; int family, r; + assert(context); + assert(key); + /* rd.route=/:[:] */ if (proc_cmdline_value_missing(key, value)) @@ -838,15 +926,21 @@ static int parse_cmdline_rd_route(Context *context, const char *key, const char } static int parse_cmdline_nameserver(Context *context, const char *key, const char *value) { + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return -EINVAL; - return network_set_dns(context, "", value); + return network_set_dns(context, "", AF_UNSPEC, value); } static int parse_cmdline_rd_peerdns(Context *context, const char *key, const char *value) { int r; + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return network_set_dhcp_use_dns(context, "", true); @@ -862,6 +956,9 @@ static int parse_cmdline_vlan(Context *context, const char *key, const char *val NetDev *netdev; int r; + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return -EINVAL; @@ -886,6 +983,9 @@ static int parse_cmdline_bridge(Context *context, const char *key, const char *v NetDev *netdev; int r; + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return -EINVAL; @@ -924,6 +1024,9 @@ static int parse_cmdline_bond(Context *context, const char *key, const char *val NetDev *netdev; int r; + assert(context); + assert(key); + if (proc_cmdline_value_missing(key, value)) return -EINVAL; @@ -981,6 +1084,9 @@ static int parse_cmdline_ifname(Context *context, const char *key, const char *v const char *name, *p; int r; + assert(context); + assert(key); + /* ifname=: */ if (proc_cmdline_value_missing(key, value)) @@ -1005,6 +1111,9 @@ static int parse_cmdline_ifname_policy(Context *context, const char *key, const Link *link; int r; + assert(context); + assert(key); + /* net.ifname-policy=policy1[,policy2,...][,] */ if (proc_cmdline_value_missing(key, value)) @@ -1135,6 +1244,9 @@ void context_clear(Context *context) { } static int address_dump(Address *address, FILE *f) { + assert(address); + assert(f); + fprintf(f, "\n[Address]\n" "Address=%s\n", @@ -1146,12 +1258,16 @@ static int address_dump(Address *address, FILE *f) { } static int route_dump(Route *route, FILE *f) { + assert(route); + assert(f); + fputs("\n[Route]\n", f); if (in_addr_is_set(route->family, &route->dest)) fprintf(f, "Destination=%s\n", IN_ADDR_PREFIX_TO_STRING(route->family, &route->dest, route->prefixlen)); - fprintf(f, "Gateway=%s\n", - IN_ADDR_TO_STRING(route->family, &route->gateway)); + if (in_addr_is_set(route->family, &route->gateway)) + fprintf(f, "Gateway=%s\n", + IN_ADDR_TO_STRING(route->family, &route->gateway)); return 0; } diff --git a/test/test-network-generator-conversion.sh b/test/test-network-generator-conversion.sh index 7c853e8987..f03847c1fa 100755 --- a/test/test-network-generator-conversion.sh +++ b/test/test-network-generator-conversion.sh @@ -280,6 +280,7 @@ COMMAND_LINES=( "ip=:::::dhcp99:dhcp6:666:52:54:00:a7:8f:ac" "ip=:::::dhcp99:dhcp6:10.0.0.128" "ip=:::::dhcp99:dhcp6:10.0.0.128:10.0.0.129" + "ip=:::::dhcp99:dhcp6:10.0.0.128:[fdef:c400:bd01:1096::bbbb]" "ip=::::::any" "ip=::::::ibft" ) @@ -301,6 +302,9 @@ INVALID_COMMAND_LINES=( "ip=fdef:c400:bd01:1096::2::[fdef:c400:bd01:1096::1]:64::ipv6:off:[fdef:c400:bd01:1096::aaaa]" "ip=[fdef:c400:bd01:1096::2]::[fdef:c400:bd01:1096::1]:64::ipv6:off:foo" "ip=[fdef:c400:bd01:1096::2]::[fdef:c400:bd01:1096::1]:64::ipv6:off:[fdef:c400:bd01:1096::aaaa]:foo" + "ip=[fdef:c400:bd01:1096::2]::[fdef:c400:bd01:1096::1]:64::ipv6:off:[fdef:c400:bd01:1096::aaaa]:[fdef:c400:bd01:1096::bbbb]:" + "ip=:::::dhcp99:dhcp6:10.0.0.128:10.0.0.129:" + "ip=:::::dhcp99:dhcp6:10.0.0.128:[fdef:c400:bd01:1096::bbbb]:" ) for cmdline in "${INVALID_COMMAND_LINES[@]}"; do (! SYSTEMD_LOG_LEVEL=debug SYSTEMD_PROC_CMDLINE="$cmdline" "$GENERATOR_BIN")