diff options
| author | Asbjørn Sloth Tønnesen <ast@fiberby.net> | 2025-09-15 14:42:51 +0000 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-09-16 08:15:48 -0700 |
| commit | 1d99aa4ed707c5630a7a7f067c8818e19167e3a1 (patch) | |
| tree | ab1a862a07d2941bc52bdbaaa3b40e6cbc54869c /tools/net/ynl/lib/ynl.c | |
| parent | 099902fc66f87424a5b4aa6d58832c7aab0ac6c6 (diff) | |
tools: ynl-gen: validate nested arrays
In nested arrays don't require that the intermediate attribute
type should be a valid attribute type, it might just be zero
or an incrementing index, it is often not even used.
See include/net/netlink.h about NLA_NESTED_ARRAY:
> The difference to NLA_NESTED is the structure:
> NLA_NESTED has the nested attributes directly inside
> while an array has the nested attributes at another
> level down and the attribute types directly in the
> nesting don't matter.
Example based on include/uapi/linux/wireguard.h:
> WGDEVICE_A_PEERS: NLA_NESTED
> 0: NLA_NESTED
> WGPEER_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
> [..]
> 0: NLA_NESTED
> ...
> ...
Previous the check required that the nested type was valid
in the parent attribute set, which in this case resolves to
WGDEVICE_A_UNSPEC, which is YNL_PT_REJECT, and it took the
early exit and returned YNL_PARSE_CB_ERROR.
This patch renames the old nl_attr_validate() to
__nl_attr_validate(), and creates a new inline function
nl_attr_validate() to mimic the old one.
The new __nl_attr_validate() takes the attribute type as an
argument, so we can use it to validate attributes of a
nested attribute, in the context of the parents attribute
type, which in the above case is generated as:
[WGDEVICE_A_PEERS] = {
.name = "peers",
.type = YNL_PT_NEST,
.nest = &wireguard_wgpeer_nest,
},
__nl_attr_validate() only checks if the attribute length
is plausible for a given attribute type, so the .nest in
the above example is not used.
As the new inline function needs to be defined after
ynl_attr_type(), then the definitions are moved down,
so we avoid a forward declaration of ynl_attr_type().
Some other examples are NL80211_BAND_ATTR_FREQS (nest) and
NL80211_ATTR_SUPPORTED_COMMANDS (u32) both in nl80211-user.c
$ make -C tools/net/ynl/generated nl80211-user.c
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Link: https://patch.msgid.link/20250915144301.725949-7-ast@fiberby.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'tools/net/ynl/lib/ynl.c')
| -rw-r--r-- | tools/net/ynl/lib/ynl.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/tools/net/ynl/lib/ynl.c b/tools/net/ynl/lib/ynl.c index 2a169c3c0797..2bcd781111d7 100644 --- a/tools/net/ynl/lib/ynl.c +++ b/tools/net/ynl/lib/ynl.c @@ -360,15 +360,15 @@ static int ynl_cb_done(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg) /* Attribute validation */ -int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr) +int __ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr, + unsigned int type) { const struct ynl_policy_attr *policy; - unsigned int type, len; unsigned char *data; + unsigned int len; data = ynl_attr_data(attr); len = ynl_attr_data_len(attr); - type = ynl_attr_type(attr); if (type > yarg->rsp_policy->max_attr) { yerr(yarg->ys, YNL_ERROR_INTERNAL, "Internal error, validating unknown attribute"); |