Update Linux to v5.4.2
Change-Id: Idf6911045d9d382da2cfe01b1edff026404ac8fd
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 25eeb6d..efccd1a 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -362,11 +362,11 @@
} else
family->attrbuf = NULL;
- family->id = idr_alloc(&genl_fam_idr, family,
- start, end + 1, GFP_KERNEL);
+ family->id = idr_alloc_cyclic(&genl_fam_idr, family,
+ start, end + 1, GFP_KERNEL);
if (family->id < 0) {
err = family->id;
- goto errout_locked;
+ goto errout_free;
}
err = genl_validate_assign_mc_groups(family);
@@ -385,6 +385,7 @@
errout_remove:
idr_remove(&genl_fam_idr, family->id);
+errout_free:
kfree(family->attrbuf);
errout_locked:
genl_unlock_all();
@@ -535,6 +536,28 @@
if (ops->dumpit == NULL)
return -EOPNOTSUPP;
+ if (!(ops->validate & GENL_DONT_VALIDATE_DUMP)) {
+ int hdrlen = GENL_HDRLEN + family->hdrsize;
+
+ if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
+ return -EINVAL;
+
+ if (family->maxattr) {
+ unsigned int validate = NL_VALIDATE_STRICT;
+
+ if (ops->validate &
+ GENL_DONT_VALIDATE_DUMP_STRICT)
+ validate = NL_VALIDATE_LIBERAL;
+ rc = __nla_validate(nlmsg_attrdata(nlh, hdrlen),
+ nlmsg_attrlen(nlh, hdrlen),
+ family->maxattr,
+ family->policy,
+ validate, extack);
+ if (rc)
+ return rc;
+ }
+ }
+
if (!family->parallel_ops) {
struct netlink_dump_control c = {
.module = family->module,
@@ -576,8 +599,13 @@
attrbuf = family->attrbuf;
if (attrbuf) {
- err = nlmsg_parse(nlh, hdrlen, attrbuf, family->maxattr,
- ops->policy, extack);
+ enum netlink_validation validate = NL_VALIDATE_STRICT;
+
+ if (ops->validate & GENL_DONT_VALIDATE_STRICT)
+ validate = NL_VALIDATE_LIBERAL;
+
+ err = __nlmsg_parse(nlh, hdrlen, attrbuf, family->maxattr,
+ family->policy, validate, extack);
if (err < 0)
goto out;
}
@@ -664,7 +692,7 @@
struct nlattr *nla_ops;
int i;
- nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS);
+ nla_ops = nla_nest_start_noflag(skb, CTRL_ATTR_OPS);
if (nla_ops == NULL)
goto nla_put_failure;
@@ -677,10 +705,10 @@
op_flags |= GENL_CMD_CAP_DUMP;
if (ops->doit)
op_flags |= GENL_CMD_CAP_DO;
- if (ops->policy)
+ if (family->policy)
op_flags |= GENL_CMD_CAP_HASPOL;
- nest = nla_nest_start(skb, i + 1);
+ nest = nla_nest_start_noflag(skb, i + 1);
if (nest == NULL)
goto nla_put_failure;
@@ -698,7 +726,7 @@
struct nlattr *nla_grps;
int i;
- nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
+ nla_grps = nla_nest_start_noflag(skb, CTRL_ATTR_MCAST_GROUPS);
if (nla_grps == NULL)
goto nla_put_failure;
@@ -708,7 +736,7 @@
grp = &family->mcgrps[i];
- nest = nla_nest_start(skb, i + 1);
+ nest = nla_nest_start_noflag(skb, i + 1);
if (nest == NULL)
goto nla_put_failure;
@@ -748,11 +776,11 @@
nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id))
goto nla_put_failure;
- nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
+ nla_grps = nla_nest_start_noflag(skb, CTRL_ATTR_MCAST_GROUPS);
if (nla_grps == NULL)
goto nla_put_failure;
- nest = nla_nest_start(skb, 1);
+ nest = nla_nest_start_noflag(skb, 1);
if (nest == NULL)
goto nla_put_failure;
@@ -937,9 +965,9 @@
static const struct genl_ops genl_ctrl_ops[] = {
{
.cmd = CTRL_CMD_GETFAMILY,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = ctrl_getfamily,
.dumpit = ctrl_dumpfamily,
- .policy = ctrl_policy,
},
};
@@ -957,6 +985,7 @@
.name = "nlctrl",
.version = 0x2,
.maxattr = CTRL_ATTR_MAX,
+ .policy = ctrl_policy,
.netnsok = true,
};