Skip to content

Commit 4fa8655

Browse files
committed
genetlink: piggy back on resv_op to default to a reject policy
To keep backward compatibility we used to leave attribute parsing to the family if no policy is specified. This becomes tedious as we move to more strict validation. Families must define reject all policies if they don't want any attributes accepted. Piggy back on the resv_start_op field as the switchover point. AFAICT only ethtool has added new commands since the resv_start_op was defined, and it has per-op policies so this should be a no-op. Nonetheless the patch should still go into v6.1 for consistency. Link: https://lore.kernel.org/all/[email protected]/ Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 9d9effc commit 4fa8655

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

include/net/genetlink.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,21 @@ struct genl_info;
4141
* @mcgrps: multicast groups used by this family
4242
* @n_mcgrps: number of multicast groups
4343
* @resv_start_op: first operation for which reserved fields of the header
44-
* can be validated, new families should leave this field at zero
44+
* can be validated and policies are required (see below);
45+
* new families should leave this field at zero
4546
* @mcgrp_offset: starting number of multicast group IDs in this family
4647
* (private)
4748
* @ops: the operations supported by this family
4849
* @n_ops: number of operations supported by this family
4950
* @small_ops: the small-struct operations supported by this family
5051
* @n_small_ops: number of small-struct operations supported by this family
52+
*
53+
* Attribute policies (the combination of @policy and @maxattr fields)
54+
* can be attached at the family level or at the operation level.
55+
* If both are present the per-operation policy takes precedence.
56+
* For operations before @resv_start_op lack of policy means that the core
57+
* will perform no attribute parsing or validation. For newer operations
58+
* if policy is not provided core will reject all TLV attributes.
5159
*/
5260
struct genl_family {
5361
int id; /* private */

net/netlink/genetlink.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,29 @@ static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) |
7878
static unsigned long *mc_groups = &mc_group_start;
7979
static unsigned long mc_groups_longs = 1;
8080

81+
/* We need the last attribute with non-zero ID therefore a 2-entry array */
82+
static struct nla_policy genl_policy_reject_all[] = {
83+
{ .type = NLA_REJECT },
84+
{ .type = NLA_REJECT },
85+
};
86+
8187
static int genl_ctrl_event(int event, const struct genl_family *family,
8288
const struct genl_multicast_group *grp,
8389
int grp_id);
8490

91+
static void
92+
genl_op_fill_in_reject_policy(const struct genl_family *family,
93+
struct genl_ops *op)
94+
{
95+
BUILD_BUG_ON(ARRAY_SIZE(genl_policy_reject_all) - 1 != 1);
96+
97+
if (op->policy || op->cmd < family->resv_start_op)
98+
return;
99+
100+
op->policy = genl_policy_reject_all;
101+
op->maxattr = 1;
102+
}
103+
85104
static const struct genl_family *genl_family_find_byid(unsigned int id)
86105
{
87106
return idr_find(&genl_fam_idr, id);
@@ -113,6 +132,8 @@ static void genl_op_from_full(const struct genl_family *family,
113132
op->maxattr = family->maxattr;
114133
if (!op->policy)
115134
op->policy = family->policy;
135+
136+
genl_op_fill_in_reject_policy(family, op);
116137
}
117138

118139
static int genl_get_cmd_full(u32 cmd, const struct genl_family *family,
@@ -142,6 +163,8 @@ static void genl_op_from_small(const struct genl_family *family,
142163

143164
op->maxattr = family->maxattr;
144165
op->policy = family->policy;
166+
167+
genl_op_fill_in_reject_policy(family, op);
145168
}
146169

147170
static int genl_get_cmd_small(u32 cmd, const struct genl_family *family,

0 commit comments

Comments
 (0)