nlmsg_ok comparison between signed and unsigned

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>
This commit is contained in:
Eric Paris 2013-01-03 14:26:00 -05:00 committed by Thomas Graf
parent 6971932254
commit 5d53626100

View file

@ -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);
}