net: netlink: Update attr validation to require exact length for some types
Attributes using NLA_U* and NLA_S* (where * is 8, 16,32 and 64) are expected to be an exact length. Split these data types from nla_attr_minlen into nla_attr_len and update validate_nla to require the attribute to have exact length for them. Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2210d6b2f2
commit
28033ae4e0
19
lib/nlattr.c
19
lib/nlattr.c
|
@ -15,19 +15,23 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <net/netlink.h>
|
#include <net/netlink.h>
|
||||||
|
|
||||||
static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = {
|
/* for these data types attribute length must be exactly given size */
|
||||||
|
static const u8 nla_attr_len[NLA_TYPE_MAX+1] = {
|
||||||
[NLA_U8] = sizeof(u8),
|
[NLA_U8] = sizeof(u8),
|
||||||
[NLA_U16] = sizeof(u16),
|
[NLA_U16] = sizeof(u16),
|
||||||
[NLA_U32] = sizeof(u32),
|
[NLA_U32] = sizeof(u32),
|
||||||
[NLA_U64] = sizeof(u64),
|
[NLA_U64] = sizeof(u64),
|
||||||
[NLA_MSECS] = sizeof(u64),
|
|
||||||
[NLA_NESTED] = NLA_HDRLEN,
|
|
||||||
[NLA_S8] = sizeof(s8),
|
[NLA_S8] = sizeof(s8),
|
||||||
[NLA_S16] = sizeof(s16),
|
[NLA_S16] = sizeof(s16),
|
||||||
[NLA_S32] = sizeof(s32),
|
[NLA_S32] = sizeof(s32),
|
||||||
[NLA_S64] = sizeof(s64),
|
[NLA_S64] = sizeof(s64),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = {
|
||||||
|
[NLA_MSECS] = sizeof(u64),
|
||||||
|
[NLA_NESTED] = NLA_HDRLEN,
|
||||||
|
};
|
||||||
|
|
||||||
static int validate_nla_bitfield32(const struct nlattr *nla,
|
static int validate_nla_bitfield32(const struct nlattr *nla,
|
||||||
u32 *valid_flags_allowed)
|
u32 *valid_flags_allowed)
|
||||||
{
|
{
|
||||||
|
@ -65,6 +69,13 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
|
||||||
|
|
||||||
BUG_ON(pt->type > NLA_TYPE_MAX);
|
BUG_ON(pt->type > NLA_TYPE_MAX);
|
||||||
|
|
||||||
|
/* for data types NLA_U* and NLA_S* require exact length */
|
||||||
|
if (nla_attr_len[pt->type]) {
|
||||||
|
if (attrlen != nla_attr_len[pt->type])
|
||||||
|
return -ERANGE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch (pt->type) {
|
switch (pt->type) {
|
||||||
case NLA_FLAG:
|
case NLA_FLAG:
|
||||||
if (attrlen > 0)
|
if (attrlen > 0)
|
||||||
|
@ -191,6 +202,8 @@ nla_policy_len(const struct nla_policy *p, int n)
|
||||||
for (i = 0; i < n; i++, p++) {
|
for (i = 0; i < n; i++, p++) {
|
||||||
if (p->len)
|
if (p->len)
|
||||||
len += nla_total_size(p->len);
|
len += nla_total_size(p->len);
|
||||||
|
else if (nla_attr_len[p->type])
|
||||||
|
len += nla_total_size(nla_attr_len[p->type]);
|
||||||
else if (nla_attr_minlen[p->type])
|
else if (nla_attr_minlen[p->type])
|
||||||
len += nla_total_size(nla_attr_minlen[p->type]);
|
len += nla_total_size(nla_attr_minlen[p->type]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue