diff options
author | Johannes Berg <johannes.berg@intel.com> | 2019-03-31 23:12:41 +0200 |
---|---|---|
committer | Hauke Mehrtens <hauke@hauke-m.de> | 2019-07-06 11:47:17 +0200 |
commit | 10b8f7ab9c71356618813fcbb320105f0c7894a3 (patch) | |
tree | b07c9a246929177464858bd4897f977ad11ccdaa /backport/backport-include/net/genetlink.h | |
parent | 25fa8919b124f8d7585327988b2a0a4a325e87d6 (diff) |
backport: Extend netlink parsing with strict validation
This extends the backported netlink handling with strict parsing. the
struct gen_ops now supports the validate member and does the validation
inside the backport layer.
This is needed to use backports with kernel 5.2.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[Hauke: Remove nla_validate_nested()]
[Hauke: Support struct genl_ops on older kernel versions]
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Diffstat (limited to 'backport/backport-include/net/genetlink.h')
-rw-r--r-- | backport/backport-include/net/genetlink.h | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/backport/backport-include/net/genetlink.h b/backport/backport-include/net/genetlink.h index 84011e72..772f10f0 100644 --- a/backport/backport-include/net/genetlink.h +++ b/backport/backport-include/net/genetlink.h @@ -91,12 +91,71 @@ void backport_genl_dump_check_consistent(struct netlink_callback *cb, #endif #endif /* LINUX_VERSION_IS_LESS(4,15,0) */ -#if LINUX_VERSION_IS_LESS(4,20,0) +#if LINUX_VERSION_IS_LESS(5,2,0) +enum genl_validate_flags { + GENL_DONT_VALIDATE_STRICT = BIT(0), + GENL_DONT_VALIDATE_DUMP = BIT(1), + GENL_DONT_VALIDATE_DUMP_STRICT = BIT(2), +}; + +#if LINUX_VERSION_IS_GEQ(3,13,0) +struct backport_genl_ops { + void *__dummy_was_policy_must_be_null; + int (*doit)(struct sk_buff *skb, + struct genl_info *info); +#if LINUX_VERSION_IS_GEQ(4,5,0) || \ + LINUX_VERSION_IN_RANGE(4,4,104, 4,5,0) || \ + LINUX_VERSION_IN_RANGE(4,1,48, 4,2,0) || \ + LINUX_VERSION_IN_RANGE(3,18,86, 3,19,0) + int (*start)(struct netlink_callback *cb); +#endif + int (*dumpit)(struct sk_buff *skb, + struct netlink_callback *cb); + int (*done)(struct netlink_callback *cb); + u8 cmd; + u8 internal_flags; + u8 flags; + u8 validate; +}; +#else +struct backport_genl_ops { + u8 cmd; + u8 internal_flags; + unsigned int flags; + void *__dummy_was_policy_must_be_null; + int (*doit)(struct sk_buff *skb, + struct genl_info *info); + int (*dumpit)(struct sk_buff *skb, + struct netlink_callback *cb); + int (*done)(struct netlink_callback *cb); + struct list_head ops_list; + u8 validate; +}; +#endif + static inline int __real_backport_genl_register_family(struct genl_family *family) { +#define OPS_VALIDATE(f) \ + BUILD_BUG_ON(offsetof(struct genl_ops, f) != \ + offsetof(struct backport_genl_ops, f)) + OPS_VALIDATE(doit); +#if LINUX_VERSION_IS_GEQ(4,5,0) || \ + LINUX_VERSION_IN_RANGE(4,4,104, 4,5,0) || \ + LINUX_VERSION_IN_RANGE(4,1,48, 4,2,0) || \ + LINUX_VERSION_IN_RANGE(3,18,86, 3,19,0) + OPS_VALIDATE(start); +#endif + OPS_VALIDATE(dumpit); + OPS_VALIDATE(done); + OPS_VALIDATE(cmd); + OPS_VALIDATE(internal_flags); + OPS_VALIDATE(flags); + return genl_register_family(family); } +#define genl_ops backport_genl_ops + static inline int __real_backport_genl_unregister_family(struct genl_family *family) { @@ -115,6 +174,7 @@ struct backport_genl_family { unsigned int maxattr; bool netnsok; bool parallel_ops; + const struct nla_policy *policy; int (*pre_doit)(__genl_const struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info); |