From: Martin Willi Date: Wed, 10 Jan 2024 15:54:17 +0000 (+0100) Subject: kernel-netlink: Handle Netlink sequence number counter overflows gracefully X-Git-Tag: android-2.5.0~9^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cdf865e0b806d5311208d78c32361c912b1e0534;p=thirdparty%2Fstrongswan.git kernel-netlink: Handle Netlink sequence number counter overflows gracefully A refcount variable is used to allocate sequential unique identifiers for Netlink sequence numbers, subject to overflows. The risk of an overflow has so far not been considered practical, as it requires 2^32 netlink requests. It seems that this issue is not only theoretical. A host with thousands of tunnels doing aggressive rekeying and/or aggressive status checking (via vici list-sas) may trigger the overflow after a few weeks uptime. The consequences are rather devastating: Once the refcount overflows, a Netlink request is sent with sequence number 0. This request is answered by the kernel, but can't be matched to the request, resulting in the error: "received unknown netlink seq 0, ignored". Without Netlink timeouts, the thread indefinitely waits for a response while holding the Netlink mutex, bringing all threads to a halt. So at all costs avoid zero sequence numbers. Also, start at sequence number 1 instead of the arbitrary 201, so the same range is used on start and after an overflow. --- diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c index 72c13a6978..339d0b9e6c 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c @@ -514,7 +514,7 @@ METHOD(netlink_socket_t, netlink_send, status_t, uintptr_t seq; u_int try; - seq = ref_get(&this->seq); + seq = ref_get_nonzero(&this->seq); for (try = 0; try <= this->retries; ++try) { @@ -694,7 +694,6 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names, .send_ack = _netlink_send_ack, .destroy = _destroy, }, - .seq = 200, .mutex = mutex_create(MUTEX_TYPE_RECURSIVE), .socket = socket(AF_NETLINK, SOCK_RAW, protocol), .entries = hashtable_create(hashtable_hash_ptr, hashtable_equals_ptr, 4),