Description of problem: The port allocation/deallocation in socket.c needs to be made thread-safe. Too many different callers hidden in libraries (netcf) may call this code at the same time and corrupt the port allocation. Concrete problem may arise in libvirt. Since I am a nice guy I provide you a patch, which I haven't tested, though: Index: lib/socket.c =================================================================== --- lib.orig/socket.c +++ lib/socket.c @@ -89,6 +89,8 @@ * @{ */ +#include <pthread.h> + #include <netlink-local.h> #include <netlink/netlink.h> #include <netlink/utils.h> @@ -117,12 +119,15 @@ static void __init init_default_cb(void) } static uint32_t used_ports_map[32]; +static pthread_mutex_t port_map_mutex = PTHREAD_MUTEX_INITIALIZER; static uint32_t generate_local_port(void) { int i, n; uint32_t pid = getpid() & 0x3FFFFF; + pthread_mutex_lock(&port_map_mutex); + for (i = 0; i < 32; i++) { if (used_ports_map[i] == 0xFFFFFFFF) continue; @@ -141,6 +146,8 @@ static uint32_t generate_local_port(void } } + pthread_mutex_unlock(&port_map_mutex); + /* Out of sockets in our own PID namespace, what to do? FIXME */ return UINT_MAX; } @@ -152,8 +159,12 @@ static void release_local_port(uint32_t if (port == UINT_MAX) return; + nr = port >> 22; - used_ports_map[nr / 32] &= ~((nr % 32) + 1); + + pthread_mutex_lock(&port_map_mutex); + used_ports_map[nr / 32] &= ~(1 << (nr & 0x1f)); + pthread_mutex_unlock(&port_map_mutex); } /** Now need to link against -lpthread as well. Version-Release number of selected component (if applicable): libnl-1.1-12.fc14.x86_64 libnl-debuginfo-1.1-12.fc14.x86_64 libnl-devel-1.1-12.fc14.x86_64
Created attachment 478874 [details] make libnl thread safe and fix a port allocation bug Here's the fix that I built libnl with. I did not link with -lpthread, so you may want to add this. Index: libnl-1.1/lib/socket.c =================================================================== --- libnl-1.1/lib.orig/socket.c +++ libnl-1.1/lib/socket.c @@ -89,6 +89,8 @@ * @{ */ +#include <pthread.h> + #include <netlink-local.h> #include <netlink/netlink.h> #include <netlink/utils.h> @@ -117,12 +119,15 @@ static void __init init_default_cb(void) } static uint32_t used_ports_map[32]; +static pthread_mutex_t port_map_mutex = PTHREAD_MUTEX_INITIALIZER; static uint32_t generate_local_port(void) { int i, n; uint32_t pid = getpid() & 0x3FFFFF; + pthread_mutex_lock(&port_map_mutex); + for (i = 0; i < 32; i++) { if (used_ports_map[i] == 0xFFFFFFFF) continue; @@ -136,11 +141,15 @@ static uint32_t generate_local_port(void /* PID_MAX_LIMIT is currently at 2^22, leaving 10 bit * to, i.e. 1024 unique ports per application. */ - return pid + (n << 22); + pthread_mutex_unlock(&port_map_mutex); + + return pid + (n << 22); } } + pthread_mutex_unlock(&port_map_mutex); + /* Out of sockets in our own PID namespace, what to do? FIXME */ return UINT_MAX; } @@ -153,7 +162,10 @@ static void release_local_port(uint32_t return; nr = port >> 22; - used_ports_map[nr / 32] &= ~((nr % 32) + 1); + + pthread_mutex_lock(&port_map_mutex); + used_ports_map[nr / 32] &= ~(1 << (nr & 0x1f)); + pthread_mutex_unlock(&port_map_mutex); } /**
Created attachment 480973 [details] patch against libnl-1.1-12 I added a hunk so that the final library also gets linked with -lpthread. This is necessary due to the mutex being used to protect the global used_ports_map.
Thomas, what do you think? What sort of solution would you apply upstream? I can ship this patch in the mean time.
libnl-1.1-14.fc15 has been submitted as an update for Fedora 15. https://admin.fedoraproject.org/updates/libnl-1.1-14.fc15
libnl-1.1-14.fc14 has been submitted as an update for Fedora 14. https://admin.fedoraproject.org/updates/libnl-1.1-14.fc14
libnl-1.1-14.fc13 has been submitted as an update for Fedora 13. https://admin.fedoraproject.org/updates/libnl-1.1-14.fc13
I can't think of any better alternatives. I will merge this upstream.
libnl-1.1-14.fc14 has been pushed to the Fedora 14 stable repository. If problems still persist, please make note of it in this bug report.
libnl-1.1-14.fc13 has been pushed to the Fedora 13 stable repository. If problems still persist, please make note of it in this bug report.
libnl-1.1-14.fc15 has been pushed to the Fedora 15 stable repository. If problems still persist, please make note of it in this bug report.