Ensuring data from netlink is within the bounds

While implementing the expression modules, a known bug raised and I was asked to fix it in the current modules I’m implementing and others modules like nft_exthdr.


The problem comes due to the netlink attributes are sent in U32 format, and sometimes, the private data in the kernel an U8 value will be enough. But it’s usual to assign directly the netlink value to the private attribute without checking if it’s bigger than U8.

For this reason, a piece of code like:

priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET]));
priv->len    = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN]));


struct nft_exthdr {
    u8                      type;
    u8                      offset;
    u8                      len;
    enum nft_registers      dreg:8;

Produces an overflow. So we’ve to ensure the value loaded with something like:

u32 offset, len;

offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET]));
len    = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN]));

if (offset > U8_MAX || len > U8_MAX)
	return -EINVAL;

priv->offset = offset;
priv->len = len;

Fixes for other cases where found and patched.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s