Module: kamailio Branch: master Commit: d2fd204b0ae35512a04702e480bb0d16878e98be URL: https://github.com/kamailio/kamailio/commit/d2fd204b0ae35512a04702e480bb0d16...
Author: Paul Komkoff i@stingr.net Committer: Paul Komkoff i@stingr.net Date: 2021-01-05T14:55:04+04:00
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.
---
Modified: src/core/socket_info.c
---
Diff: https://github.com/kamailio/kamailio/commit/d2fd204b0ae35512a04702e480bb0d16... Patch: https://github.com/kamailio/kamailio/commit/d2fd204b0ae35512a04702e480bb0d16...
---
diff --git a/src/core/socket_info.c b/src/core/socket_info.c index a46aba24ad..d34f3fb4cd 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;