summaryrefslogtreecommitdiffstats
path: root/lib/nl.c
diff options
context:
space:
mode:
authorAndrey Vagin <avagin@openvz.org>2015-09-14 15:59:58 (GMT)
committerThomas Haller <thaller@redhat.com>2015-09-21 09:57:45 (GMT)
commitfd9d1da28c9d989f88b6c5edaa352c01976f82ac (patch)
tree7c87947c81ac6b7a54ec11a27c753e0046909854 /lib/nl.c
parent69851e24c7db9474316c5d97caf5e645fac69816 (diff)
downloadlibnl-fd9d1da28c9d989f88b6c5edaa352c01976f82ac.zip
libnl-fd9d1da28c9d989f88b6c5edaa352c01976f82ac.tar.gz
libnl-fd9d1da28c9d989f88b6c5edaa352c01976f82ac.tar.bz2
libnl: report an error if unexpected control data was received
Currently, we try to handle MSG_CTRUNC, but if msg_controllen is zero, we make double free for the same address. realloc(0, 0) returns non-zero address realloc(addr, 0) returns zero and free(addr) has already been called Then we call free(addr) again and get an error like this: *** Error in `./task_diag_all': double free or corruption (fasttop): 0x0000000000f9c160 *** ======= Backtrace: ========= /lib64/libc.so.6(+0x77e9d)[0x7f360ed96e9d] /lib64/libc.so.6(+0x7f53c)[0x7f360ed9e53c] /lib64/libc.so.6(cfree+0x4c)[0x7f360eda2e9c] /lib64/libnl-3.so.200(nl_recv+0x221)[0x7f360f2f6361] /lib64/libnl-3.so.200(nl_recvmsgs_report+0x555)[0x7f360f2f6a95] /lib64/libnl-3.so.200(nl_recvmsgs+0x9)[0x7f360f2f6d89] ./task_diag_all[0x400f8d] /lib64/libc.so.6(__libc_start_main+0xf0)[0x7f360ed3f790] ./task_diag_all[0x401169] http://lists.infradead.org/pipermail/libnl/2015-September/001965.html Signed-off-by: Andrey Vagin <avagin@openvz.org> Signed-off-by: Thomas Haller <thaller@redhat.com>
Diffstat (limited to 'lib/nl.c')
-rw-r--r--lib/nl.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/lib/nl.c b/lib/nl.c
index c93b6a5..cba4217 100644
--- a/lib/nl.c
+++ b/lib/nl.c
@@ -721,6 +721,13 @@ retry:
if (msg.msg_flags & MSG_CTRUNC) {
void *tmp;
+
+ if (msg.msg_controllen == 0) {
+ retval = -NLE_MSG_TRUNC;
+ NL_DBG(4, "recvmsg(%p): Received unexpected control data", sk);
+ goto abort;
+ }
+
msg.msg_controllen *= 2;
tmp = realloc(msg.msg_control, msg.msg_controllen);
if (!tmp) {