[PATCH 3/3] virarptable: End parsing earlier in case of NLMSG_DONE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Check for the last multipart message right as the first thing.  The
presumption probably was that the last message might still contain a
payload we want to parse.  However that cannot be true since that would
have to be a type RTM_NEWNEIGH.  This was not caught because older
kernels were note sending NLMSG_DONE and probably relied on the fact
that the parsing just stops after all the messages are walked through,
which the NLMSG_OK macro successfully did.

Resolves: https://issues.redhat.com/browse/RHEL-52449
Signed-off-by: Martin Kletzander <mkletzan@xxxxxxxxxx>
---
So technically this still has some issues, maybe.

I could not find if our usage of libnl3 makes it easier for us so that we do not
have to check for NLMSG_{ERROR,OVERRUN,NOOP} or whether these checks should be
here as well.  If yes, then we should add them.  And we have (some of) these
checks elsewhere in the code, so "maybe".

Another thing is that we could avoid such errors by using nl_socket_set_cb(),
calling nl_recvmsgs_default() and then parsing only the valid messages in a
callback.  On top of that we could have an abstraction on top this to utilise in
all the netlink dumps we do, ditching our current abstraction which was a bit
hard for me to go through, to be honest.

And of course there might be other places in our codebase that expect the same
behaviour as this code did and we should fix 'em all.  After all the debugging
for this piece I did not even check for those, maybe if this gets in I'll have a
long think about it.

 src/util/virarptable.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/util/virarptable.c b/src/util/virarptable.c
index 8e805fb35332..604019c62a37 100644
--- a/src/util/virarptable.c
+++ b/src/util/virarptable.c
@@ -84,6 +84,9 @@ virArpTableGet(void)
         int len = nh->nlmsg_len;
         void *addr;
 
+        if (nh->nlmsg_type == NLMSG_DONE)
+            return table;
+
         if (len < NLMSG_SPACE(sizeof(*r))) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("wrong nlmsg len"));
@@ -98,9 +101,6 @@ virArpTableGet(void)
             (!(r->ndm_state == NUD_STALE || r->ndm_state == NUD_REACHABLE)))
             continue;
 
-        if (nh->nlmsg_type == NLMSG_DONE)
-            return table;
-
         VIR_WARNINGS_NO_CAST_ALIGN
         parse_rtattr(tb, NDA_MAX, NDA_RTA(r), NLMSG_PAYLOAD(nh, sizeof(*r)));
         VIR_WARNINGS_RESET
-- 
2.46.0




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux