1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-29 06:50:16 +03:00

network: refuse to configure address or route with 0 valid lifetime

Fixes #23625.
This commit is contained in:
Yu Watanabe 2022-07-14 02:39:56 +09:00
parent 5235d73960
commit b9e4ec500e
2 changed files with 40 additions and 20 deletions

View File

@ -212,7 +212,7 @@ void address_set_broadcast(Address *a, Link *link) {
a->broadcast.s_addr = a->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> a->prefixlen);
}
static struct ifa_cacheinfo *address_set_cinfo(Manager *m, const Address *a, struct ifa_cacheinfo *cinfo) {
static void address_set_cinfo(Manager *m, const Address *a, struct ifa_cacheinfo *cinfo) {
usec_t now_usec;
assert(m);
@ -225,8 +225,6 @@ static struct ifa_cacheinfo *address_set_cinfo(Manager *m, const Address *a, str
.ifa_valid = usec_to_sec(a->lifetime_valid_usec, now_usec),
.ifa_prefered = usec_to_sec(a->lifetime_preferred_usec, now_usec),
};
return cinfo;
}
static void address_set_lifetime(Manager *m, Address *a, const struct ifa_cacheinfo *cinfo) {
@ -1030,12 +1028,13 @@ int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m,
return 1;
}
static int address_configure(const Address *address, Link *link, Request *req) {
static int address_configure(const Address *address, const struct ifa_cacheinfo *c, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
assert(address);
assert(IN_SET(address->family, AF_INET, AF_INET6));
assert(c);
assert(link);
assert(link->ifindex > 0);
assert(link->manager);
@ -1072,8 +1071,7 @@ static int address_configure(const Address *address, Link *link, Request *req) {
return r;
}
r = sd_netlink_message_append_cache_info(m, IFA_CACHEINFO,
address_set_cinfo(link->manager, address, &(struct ifa_cacheinfo) {}));
r = sd_netlink_message_append_cache_info(m, IFA_CACHEINFO, c);
if (r < 0)
return r;
@ -1102,6 +1100,7 @@ static bool address_is_ready_to_configure(Link *link, const Address *address) {
}
static int address_process_request(Request *req, Link *link, Address *address) {
struct ifa_cacheinfo c;
int r;
assert(req);
@ -1111,7 +1110,16 @@ static int address_process_request(Request *req, Link *link, Address *address) {
if (!address_is_ready_to_configure(link, address))
return 0;
r = address_configure(address, link, req);
address_set_cinfo(link->manager, address, &c);
if (c.ifa_valid == 0) {
log_link_debug(link, "Refuse to configure %s address %s, as its valid lifetime is zero.",
network_config_source_to_string(address->source),
IN_ADDR_PREFIX_TO_STRING(address->family, &address->in_addr, address->prefixlen));
address_cancel_requesting(address);
return 1;
}
r = address_configure(address, &c, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure address: %m");

View File

@ -1153,7 +1153,7 @@ int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Li
return 1;
}
static int route_configure(const Route *route, Link *link, Request *req) {
static int route_configure(const Route *route, uint32_t lifetime_sec, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
@ -1179,17 +1179,10 @@ static int route_configure(const Route *route, Link *link, Request *req) {
if (r < 0)
return r;
if (route->lifetime_usec != USEC_INFINITY) {
usec_t now_usec;
uint32_t sec;
assert_se(sd_event_now(link->manager->event, CLOCK_BOOTTIME, &now_usec) >= 0);
sec = usec_to_sec(route->lifetime_usec, now_usec);
if (sec != UINT32_MAX) {
r = sd_netlink_message_append_u32(m, RTA_EXPIRES, sec);
if (r < 0)
return r;
}
if (lifetime_sec != UINT32_MAX) {
r = sd_netlink_message_append_u32(m, RTA_EXPIRES, lifetime_sec);
if (r < 0)
return r;
}
if (route->ttl_propagate >= 0) {
@ -1324,6 +1317,7 @@ static int route_process_request(Request *req, Link *link, Route *route) {
assert(req);
assert(link);
assert(link->manager);
assert(route);
r = route_is_ready_to_configure(route, link);
@ -1362,7 +1356,25 @@ static int route_process_request(Request *req, Link *link, Route *route) {
}
}
r = route_configure(route, link, req);
usec_t now_usec;
assert_se(sd_event_now(link->manager->event, CLOCK_BOOTTIME, &now_usec) >= 0);
uint32_t sec = usec_to_sec(route->lifetime_usec, now_usec);
if (sec == 0) {
log_link_debug(link, "Refuse to configure %s route with zero lifetime.",
network_config_source_to_string(route->source));
if (converted)
for (size_t i = 0; i < converted->n; i++) {
Route *existing;
assert_se(route_get(link->manager, converted->links[i] ?: link, converted->routes[i], &existing) >= 0);
route_cancel_requesting(existing);
}
else
route_cancel_requesting(route);
}
r = route_configure(route, sec, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure route: %m");