netlink: specs: handshake: do not accept the handler-class sentinel

"max" is the exclusive upper bound of enum handshake_handler_class, not
a class a handler can ask for, but the spec lists it as a plain entry.
_init_checks() derives the policy limit from the highest entry, so the
generated policy came out as NLA_POLICY_MAX(NLA_U32, 2) and
handshake_nl_accept_doit() takes class 2 all the way into
handshake_req_next(), which walks hn_requests under hn_lock before
returning -EAGAIN instead of the -EINVAL a bad class deserves.

render-max is how YNL spells this, and unlike a hand written limit it
stays correct when a second handler class is added.

It does change what HANDSHAKE_HANDLER_CLASS_MAX means - the highest
valid class rather than one past it, as in every other Netlink/YNL
family - with the count left as __HANDSHAKE_HANDLER_CLASS_MAX.
The constant is uAPI, but I could not find any user space user,
this constant seems to have been added for kernel's benefit.

I think the risk of changing this is worth taking, having MAX
with different semantics than the rest of Netlink is very confusing.

Acked-by: Chuck Lever <cel@kernel.org>
Reviewed-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
Link: https://patch.msgid.link/20260904190410.3864660-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-09-04 12:04:10 -07:00
parent f5134d7347
commit fd0291fad9
5 changed files with 9 additions and 5 deletions

View File

@ -22,7 +22,8 @@ definitions:
type: enum
name: handler-class
value-start: 0
entries: [none, tlshd, max]
entries: [none, tlshd]
render-max: true
-
type: enum
name: msg-type

View File

@ -13,7 +13,10 @@
enum handshake_handler_class {
HANDSHAKE_HANDLER_CLASS_NONE,
HANDSHAKE_HANDLER_CLASS_TLSHD,
HANDSHAKE_HANDLER_CLASS_MAX,
/* private: */
__HANDSHAKE_HANDLER_CLASS_MAX,
HANDSHAKE_HANDLER_CLASS_MAX = (__HANDSHAKE_HANDLER_CLASS_MAX - 1)
};
enum handshake_msg_type {

View File

@ -14,7 +14,7 @@
/* HANDSHAKE_CMD_ACCEPT - do */
static const struct nla_policy handshake_accept_nl_policy[HANDSHAKE_A_ACCEPT_HANDLER_CLASS + 1] = {
[HANDSHAKE_A_ACCEPT_HANDLER_CLASS] = NLA_POLICY_MAX(NLA_U32, 2),
[HANDSHAKE_A_ACCEPT_HANDLER_CLASS] = NLA_POLICY_MAX(NLA_U32, 1),
};
/* HANDSHAKE_CMD_DONE - do */

View File

@ -42,7 +42,7 @@ static struct handshake_proto handshake_req_alloc_proto_2 = {
};
static struct handshake_proto handshake_req_alloc_proto_3 = {
.hp_handler_class = HANDSHAKE_HANDLER_CLASS_MAX,
.hp_handler_class = __HANDSHAKE_HANDLER_CLASS_MAX,
};
static struct handshake_proto handshake_req_alloc_proto_4 = {

View File

@ -115,7 +115,7 @@ struct handshake_req *handshake_req_alloc(const struct handshake_proto *proto,
return NULL;
if (proto->hp_handler_class <= HANDSHAKE_HANDLER_CLASS_NONE)
return NULL;
if (proto->hp_handler_class >= HANDSHAKE_HANDLER_CLASS_MAX)
if (proto->hp_handler_class > HANDSHAKE_HANDLER_CLASS_MAX)
return NULL;
if (!proto->hp_accept || !proto->hp_done)
return NULL;