From d2fd204b0ae35512a04702e480bb0d16878e98be Mon Sep 17 00:00:00 2001 From: Paul Komkoff Date: Mon, 4 Jan 2021 18:13:28 +0400 Subject: [PATCH 1/2] core: work around interface enum buffer overrun When a system has too many interfaces and too many addresses, 8 kilobytes isn't enough to fit all of the netlink responses. As the result, kamailio gets stuck in a loop where it tries to do a 0-length recv. Increase the buffer to 32K. It's a miniscule amount for modern times anyway. Also, add diagnostics to make further troubleshooting easier. Proper fix would be to switch to libnl here, which would make a good weekend project. --- src/core/socket_info.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/core/socket_info.c b/src/core/socket_info.c index a46aba24ad6..d34f3fb4cd6 100644 --- a/src/core/socket_info.c +++ b/src/core/socket_info.c @@ -1070,6 +1070,7 @@ static int nl_bound_sock(void) req.g.rtgen_family = family;\ } while(0); +#define NETLINK_BUFFER_SIZE 32768 static int get_flags(int family){ struct { @@ -1079,7 +1080,7 @@ static int get_flags(int family){ int rtn = 0; struct nlmsghdr* nlp; struct ifinfomsg *ifi; - char buf[8192]; + char buf[NETLINK_BUFFER_SIZE]; char *p = buf; int nll = 0; int nl_sock = -1; @@ -1095,6 +1096,10 @@ static int get_flags(int family){ } while(1) { + if ((sizeof(buf) - nll) == 0) { + LM_ERR("netlink buffer overflow in get_flags"); + goto error; + } rtn = recv(nl_sock, p, sizeof(buf) - nll, 0); nlp = (struct nlmsghdr *) p; if(nlp->nlmsg_type == NLMSG_DONE){ @@ -1148,7 +1153,7 @@ static int build_iface_list(void) struct nlmsghdr* nlp; struct ifaddrmsg *ifi; int rtl; - char buf[8192]; + char buf[NETLINK_BUFFER_SIZE]; char *p = buf; int nll = 0; struct rtattr * rtap; @@ -1184,6 +1189,10 @@ static int build_iface_list(void) nll = 0; p = buf; while(1) { + if ((sizeof(buf) - nll) == 0) { + LM_ERR("netlink buffer overflow in build_iface_list"); + goto error; + } rtn = recv(nl_sock, p, sizeof(buf) - nll, 0); LM_DBG("received %d byles \n", rtn); nlp = (struct nlmsghdr *) p; From 42f7702430c312b2c9caea8f617af4e3719ef12f Mon Sep 17 00:00:00 2001 From: Paul Komkoff Date: Mon, 4 Jan 2021 18:18:01 +0400 Subject: [PATCH 2/2] core: fix unused argument in socket_info.c:get_flags get_flags has an argument - family - which is supposed to be used in netlink message, otherwise why would we need it? --- src/core/socket_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/socket_info.c b/src/core/socket_info.c index d34f3fb4cd6..d55f506bcc5 100644 --- a/src/core/socket_info.c +++ b/src/core/socket_info.c @@ -1085,7 +1085,7 @@ static int get_flags(int family){ int nll = 0; int nl_sock = -1; - fill_nl_req(req, RTM_GETLINK, AF_INET); + fill_nl_req(req, RTM_GETLINK, family); if((nl_sock = nl_bound_sock()) < 0) return -1;