From 19f14dbf37d4b024fc5d8ccdaa7aefc275a9bce2 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 13 Jul 2022 11:26:00 +0200 Subject: [PATCH] platform/netlink: adjust integer types in netlink API - use proper integer types. A netlink message cannot be as large as size_t, because the length is tracked in an uint32_t. Use the right types. - fields like "nlmsg_type" or "nlmsg_flags" are uint16_t. Use the right types. - note that nlmsg_size() still returns and accepts "int". Maybe the should be adjusted too, but we use macros from kernel headers, which also use int. Even if that is not the type of the length on the binary protocol. So some of these functions still use int, to be closer and compatible with . --- src/libnm-platform/nm-linux-platform.c | 32 +++++---- src/libnm-platform/nm-netlink.c | 67 +++++++++++-------- src/libnm-platform/nm-netlink.h | 24 ++++--- .../wifi/nm-wifi-utils-nl80211.c | 6 +- src/libnm-platform/wpan/nm-wpan-utils.c | 6 +- 5 files changed, 77 insertions(+), 58 deletions(-) diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index cd4c4f9a9..185c9aed3 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -4732,8 +4732,8 @@ nla_put_failure: } static struct nl_msg * -_nl_msg_new_link_full(int nlmsg_type, - int nlmsg_flags, +_nl_msg_new_link_full(uint16_t nlmsg_type, + uint16_t nlmsg_flags, int ifindex, const char *ifname, guint8 family, @@ -4765,15 +4765,15 @@ nla_put_failure: } static struct nl_msg * -_nl_msg_new_link(int nlmsg_type, int nlmsg_flags, int ifindex, const char *ifname) +_nl_msg_new_link(uint16_t nlmsg_type, uint16_t nlmsg_flags, int ifindex, const char *ifname) { return _nl_msg_new_link_full(nlmsg_type, nlmsg_flags, ifindex, ifname, AF_UNSPEC, 0, 0); } /* Copied and modified from libnl3's build_addr_msg(). */ static struct nl_msg * -_nl_msg_new_address(int nlmsg_type, - int nlmsg_flags, +_nl_msg_new_address(uint16_t nlmsg_type, + uint16_t nlmsg_flags, int family, int ifindex, gconstpointer address, @@ -4887,7 +4887,7 @@ ip_route_ignored_protocol(const NMPlatformIPRoute *route) /* Copied and modified from libnl3's build_route_msg() and rtnl_route_build_msg(). */ static struct nl_msg * -_nl_msg_new_route(int nlmsg_type, guint16 nlmsgflags, const NMPObject *obj) +_nl_msg_new_route(uint16_t nlmsg_type, uint16_t nlmsg_flags, const NMPObject *obj) { nm_auto_nlmsg struct nl_msg *msg = NULL; const NMPClass *klass = NMP_OBJECT_GET_CLASS(obj); @@ -4914,7 +4914,7 @@ _nl_msg_new_route(int nlmsg_type, guint16 nlmsgflags, const NMPObject *obj) NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); nm_assert(NM_IN_SET(nlmsg_type, RTM_NEWROUTE, RTM_DELROUTE)); - msg = nlmsg_alloc_simple(nlmsg_type, (int) nlmsgflags); + msg = nlmsg_alloc_simple(nlmsg_type, nlmsg_flags); if (nlmsg_append_struct(msg, &rtmsg) < 0) goto nla_put_failure; @@ -4998,7 +4998,9 @@ nla_put_failure: } static struct nl_msg * -_nl_msg_new_routing_rule(int nlmsg_type, int nlmsg_flags, const NMPlatformRoutingRule *routing_rule) +_nl_msg_new_routing_rule(uint16_t nlmsg_type, + uint16_t nlmsg_flags, + const NMPlatformRoutingRule *routing_rule) { nm_auto_nlmsg struct nl_msg *msg = NULL; const guint8 addr_size = nm_utils_addr_family_to_size(routing_rule->addr_family); @@ -5111,7 +5113,7 @@ nla_put_failure: } static struct nl_msg * -_nl_msg_new_qdisc(int nlmsg_type, int nlmsg_flags, const NMPlatformQdisc *qdisc) +_nl_msg_new_qdisc(uint16_t nlmsg_type, uint16_t nlmsg_flags, const NMPlatformQdisc *qdisc) { nm_auto_nlmsg struct nl_msg *msg = NULL; struct nlattr *tc_options; @@ -5198,7 +5200,7 @@ nla_put_failure: } static struct nl_msg * -_nl_msg_new_tfilter(int nlmsg_type, int nlmsg_flags, const NMPlatformTfilter *tfilter) +_nl_msg_new_tfilter(uint16_t nlmsg_type, uint16_t nlmsg_flags, const NMPlatformTfilter *tfilter) { nm_auto_nlmsg struct nl_msg *msg = NULL; struct nlattr *tc_options; @@ -9274,7 +9276,11 @@ qdisc_add(NMPlatform *platform, NMPNlmFlags flags, const NMPlatformQdisc *qdisc) } static int -tc_delete(NMPlatform *platform, int nlmsgtype, int ifindex, guint32 parent, gboolean log_error) +tc_delete(NMPlatform *platform, + uint16_t nlmsg_type, + int ifindex, + guint32 parent, + gboolean log_error) { WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; gs_free char *errmsg = NULL; @@ -9287,7 +9293,7 @@ tc_delete(NMPlatform *platform, int nlmsgtype, int ifindex, guint32 parent, gboo .tcm_parent = parent, }; - switch (nlmsgtype) { + switch (nlmsg_type) { case RTM_DELQDISC: log_tag = "do-delete-qdisc"; break; @@ -9299,7 +9305,7 @@ tc_delete(NMPlatform *platform, int nlmsgtype, int ifindex, guint32 parent, gboo log_tag = "do-delete-tc"; } - msg = nlmsg_alloc_simple(nlmsgtype, NMP_NLM_FLAG_F_ECHO); + msg = nlmsg_alloc_simple(nlmsg_type, NMP_NLM_FLAG_F_ECHO); if (nlmsg_append_struct(msg, &tcm) < 0) goto nla_put_failure; diff --git a/src/libnm-platform/nm-netlink.c b/src/libnm-platform/nm-netlink.c index f6b1d8b88..cb5bd4a89 100644 --- a/src/libnm-platform/nm-netlink.c +++ b/src/libnm-platform/nm-netlink.c @@ -38,7 +38,7 @@ struct nl_msg { struct sockaddr_nl nm_dst; struct ucred nm_creds; struct nlmsghdr *nm_nlh; - size_t nm_size; + uint32_t nm_size; bool nm_creds_has : 1; }; @@ -261,23 +261,26 @@ nlmsg_hdr(struct nl_msg *n) } void * -nlmsg_reserve(struct nl_msg *n, size_t len, int pad) +nlmsg_reserve(struct nl_msg *n, uint32_t len, uint32_t pad) { - char *buf = (char *) n->nm_nlh; - size_t nlmsg_len = n->nm_nlh->nlmsg_len; - size_t tlen; + char *buf = (char *) n->nm_nlh; + uint32_t tlen; - nm_assert(pad >= 0); + nm_assert(n); + nm_assert(pad == 0 || nm_utils_is_power_of_two(pad)); + nm_assert(n->nm_nlh->nlmsg_len <= n->nm_size); - if (len > n->nm_size) + if (pad != 0) { + tlen = (len + (pad - 1u)) & ~(pad - 1u); + if (tlen < len) + return NULL; + } else + tlen = len; + + if (tlen > n->nm_size - n->nm_nlh->nlmsg_len) return NULL; - tlen = pad ? ((len + (pad - 1)) & ~(pad - 1)) : len; - - if ((tlen + nlmsg_len) > n->nm_size) - return NULL; - - buf += nlmsg_len; + buf += n->nm_nlh->nlmsg_len; n->nm_nlh->nlmsg_len += tlen; if (tlen > len) @@ -322,6 +325,8 @@ nlmsg_alloc_size(size_t len) if (len < sizeof(struct nlmsghdr)) len = sizeof(struct nlmsghdr); + else if (len > UINT32_MAX) + g_return_val_if_reached(NULL); nm = g_slice_new(struct nl_msg); *nm = (struct nl_msg){ @@ -359,7 +364,7 @@ nlmsg_alloc_convert(struct nlmsghdr *hdr) } struct nl_msg * -nlmsg_alloc_simple(int nlmsgtype, int flags) +nlmsg_alloc_simple(uint16_t nlmsgtype, uint16_t flags) { struct nl_msg *nm; struct nlmsghdr *new; @@ -384,20 +389,20 @@ nlmsg_free(struct nl_msg *msg) /*****************************************************************************/ int -nlmsg_append(struct nl_msg *n, const void *data, size_t len, int pad) +nlmsg_append(struct nl_msg *n, const void *data, uint32_t len, uint32_t pad) { void *tmp; nm_assert(n); - nm_assert(data); - nm_assert(len > 0); - nm_assert(pad >= 0); + nm_assert(len == 0 || data); tmp = nlmsg_reserve(n, len, pad); - if (tmp == NULL) + if (!tmp) return -ENOMEM; - memcpy(tmp, data, len); + if (len > 0) + memcpy(tmp, data, len); + return 0; } @@ -417,14 +422,17 @@ nlmsg_parse(const struct nlmsghdr *nlh, } struct nlmsghdr * -nlmsg_put(struct nl_msg *n, uint32_t pid, uint32_t seq, int type, int payload, int flags) +nlmsg_put(struct nl_msg *n, + uint32_t pid, + uint32_t seq, + uint16_t type, + uint32_t payload, + uint16_t flags) { - struct nlmsghdr *nlh; + struct nlmsghdr *nlh = (struct nlmsghdr *) n->nm_nlh; - if (n->nm_nlh->nlmsg_len < NLMSG_HDRLEN) - g_return_val_if_reached(NULL); + nm_assert(nlh->nlmsg_len >= NLMSG_HDRLEN); - nlh = (struct nlmsghdr *) n->nm_nlh; nlh->nlmsg_type = type; nlh->nlmsg_flags = flags; nlh->nlmsg_pid = pid; @@ -565,7 +573,8 @@ nla_nest_start(struct nl_msg *msg, int attrtype) static int _nest_end(struct nl_msg *msg, struct nlattr *start, int keep_empty) { - size_t pad, len; + size_t len; + uint32_t pad; len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) start; @@ -734,9 +743,9 @@ void * genlmsg_put(struct nl_msg *msg, uint32_t port, uint32_t seq, - int family, - int hdrlen, - int flags, + uint16_t family, + uint32_t hdrlen, + uint16_t flags, uint8_t cmd, uint8_t version) { diff --git a/src/libnm-platform/nm-netlink.h b/src/libnm-platform/nm-netlink.h index efc958531..852c9c8f6 100644 --- a/src/libnm-platform/nm-netlink.h +++ b/src/libnm-platform/nm-netlink.h @@ -60,7 +60,7 @@ struct nl_msg_lite { const struct sockaddr_nl *nm_dst; const struct ucred *nm_creds; const struct nlmsghdr *nm_nlh; - size_t nm_size; + uint32_t nm_size; }; /*****************************************************************************/ @@ -389,13 +389,13 @@ struct nl_msg *nlmsg_alloc_size(size_t max); struct nl_msg *nlmsg_alloc_convert(struct nlmsghdr *hdr); -struct nl_msg *nlmsg_alloc_simple(int nlmsgtype, int flags); +struct nl_msg *nlmsg_alloc_simple(uint16_t nlmsgtype, uint16_t flags); -void *nlmsg_reserve(struct nl_msg *n, size_t len, int pad); +void *nlmsg_reserve(struct nl_msg *n, uint32_t len, uint32_t pad); -int nlmsg_append(struct nl_msg *n, const void *data, size_t len, int pad); +int nlmsg_append(struct nl_msg *n, const void *data, uint32_t len, uint32_t pad); -#define nlmsg_append_struct(n, data) nlmsg_append(n, (data), sizeof(*(data)), NLMSG_ALIGNTO) +#define nlmsg_append_struct(n, data) (nlmsg_append((n), (data), sizeof(*(data)), NLMSG_ALIGNTO)) void nlmsg_free(struct nl_msg *msg); @@ -502,8 +502,12 @@ int nlmsg_parse(const struct nlmsghdr *nlh, nlmsg_parse((nlh), (hdrlen), (tb), G_N_ELEMENTS(tb) - 1, (policy)); \ }) -struct nlmsghdr * -nlmsg_put(struct nl_msg *n, uint32_t pid, uint32_t seq, int type, int payload, int flags); +struct nlmsghdr *nlmsg_put(struct nl_msg *n, + uint32_t pid, + uint32_t seq, + uint16_t type, + uint32_t payload, + uint16_t flags); /*****************************************************************************/ @@ -614,9 +618,9 @@ extern const struct nla_policy genl_ctrl_policy[8]; void *genlmsg_put(struct nl_msg *msg, uint32_t port, uint32_t seq, - int family, - int hdrlen, - int flags, + uint16_t family, + uint32_t hdrlen, + uint16_t flags, uint8_t cmd, uint8_t version); void *genlmsg_data(const struct genlmsghdr *gnlh); diff --git a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c index bd56885dd..1875a4206 100644 --- a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c @@ -83,12 +83,12 @@ error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) } static struct nl_msg * -_nl80211_alloc_msg(guint16 genl_family_id, int ifindex, int phy, guint32 cmd, guint32 flags) +_nl80211_alloc_msg(guint16 genl_family_id, int ifindex, int phy, uint8_t cmd, uint16_t flags) { nm_auto_nlmsg struct nl_msg *msg = NULL; msg = nlmsg_alloc(); - genlmsg_put(msg, 0, 0, genl_family_id, 0, flags, cmd, 0); + genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, genl_family_id, 0, flags, cmd, 0); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex); if (phy != -1) NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, phy); @@ -99,7 +99,7 @@ nla_put_failure: } static struct nl_msg * -nl80211_alloc_msg(NMWifiUtilsNl80211 *self, guint32 cmd, guint32 flags) +nl80211_alloc_msg(NMWifiUtilsNl80211 *self, uint8_t cmd, uint16_t flags) { return _nl80211_alloc_msg(self->genl_family_id, self->parent.ifindex, self->phy, cmd, flags); } diff --git a/src/libnm-platform/wpan/nm-wpan-utils.c b/src/libnm-platform/wpan/nm-wpan-utils.c index 8fa0003f6..0afbe58d3 100644 --- a/src/libnm-platform/wpan/nm-wpan-utils.c +++ b/src/libnm-platform/wpan/nm-wpan-utils.c @@ -75,12 +75,12 @@ error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) } static struct nl_msg * -_nl802154_alloc_msg(guint16 genl_family_id, int ifindex, guint32 cmd, guint32 flags) +_nl802154_alloc_msg(guint16 genl_family_id, int ifindex, uint8_t cmd, uint16_t flags) { nm_auto_nlmsg struct nl_msg *msg = NULL; msg = nlmsg_alloc(); - genlmsg_put(msg, 0, 0, genl_family_id, 0, flags, cmd, 0); + genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, genl_family_id, 0, flags, cmd, 0); NLA_PUT_U32(msg, NL802154_ATTR_IFINDEX, ifindex); return g_steal_pointer(&msg); @@ -89,7 +89,7 @@ nla_put_failure: } static struct nl_msg * -nl802154_alloc_msg(NMWpanUtils *self, guint32 cmd, guint32 flags) +nl802154_alloc_msg(NMWpanUtils *self, uint8_t cmd, uint16_t flags) { return _nl802154_alloc_msg(self->genl_family_id, self->ifindex, cmd, flags); }