]> granicus.if.org Git - libnl/commitdiff
nlmsg_ok comparison between signed and unsigned
authorEric Paris <eparis@redhat.com>
Thu, 3 Jan 2013 19:26:00 +0000 (14:26 -0500)
committerThomas Graf <tgraf@suug.ch>
Thu, 3 Jan 2013 23:35:18 +0000 (00:35 +0100)
The nlmsg_ok macro has a comparison between an int and a size_t
(unsigned int).  The C spec says the int is cast to unsigned int before
the comparison.  This is a problem as the audit system will send skb's
with skb->len == nlhhdr->nlmsg_len which are NOT aligned.  Thus you can
end up with remaining being negative.  So the comparison becomes

(unsigned int)(-1) >= (unsigned int)16

Which turns out to be true!  It should clearly be false.  So if we cast
the size_t to an int we get a signed comparison and it works.  (This is
what linux/netlink.h and all of the kernel netlink headers do)

Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
lib/msg.c

index 23c137d121e4415819fe36cfb395b65dc33fc256..2613c78145eb7a5f6b248129801cc114c9179e24 100644 (file)
--- a/lib/msg.c
+++ b/lib/msg.c
@@ -178,7 +178,7 @@ int nlmsg_valid_hdr(const struct nlmsghdr *nlh, int hdrlen)
  */
 int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
 {
-       return (remaining >= sizeof(struct nlmsghdr) &&
+       return (remaining >= (int)sizeof(struct nlmsghdr) &&
                nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
                nlh->nlmsg_len <= remaining);
 }