Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157423061
D56915.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D56915.diff
View Options
diff --git a/sys/netlink/netlink_message_parser.h b/sys/netlink/netlink_message_parser.h
--- a/sys/netlink/netlink_message_parser.h
+++ b/sys/netlink/netlink_message_parser.h
@@ -222,6 +222,9 @@
void nlmsg_report_cookie(struct nl_pstate *npt, struct nlattr *nla);
void nlmsg_report_cookie_u32(struct nl_pstate *npt, uint32_t val);
+struct nlmsghdr *nl_alloc_compat_hdr(struct nlmsghdr *hdr, uint32_t len,
+ struct nl_pstate *npt);
+
/*
* Have it inline so compiler can optimize field accesses into
* the list of direct function calls without iteration.
@@ -232,27 +235,7 @@
{
int error;
- if (__predict_false(len < parser->nl_hdr_off)) {
- void *tmp_hdr;
-
- if (npt->strict) {
- nlmsg_report_err_msg(npt,
- "header too short: expected %d, got %d",
- parser->nl_hdr_off, len);
- return (EINVAL);
- }
-
- /*
- * Compatibility with older applications:
- * pretend there's a full header.
- */
- tmp_hdr = npt_alloc(npt, parser->nl_hdr_off);
- if (tmp_hdr == NULL)
- return (EINVAL);
- memcpy(tmp_hdr, hdr, len);
- hdr = tmp_hdr;
- len = parser->nl_hdr_off;
- }
+ MPASS(len >= parser->nl_hdr_off);
if (npt->strict && parser->sp != NULL && !parser->sp(hdr, npt))
return (EINVAL);
@@ -320,6 +303,10 @@
nl_parse_nlmsg(struct nlmsghdr *hdr, const struct nlhdr_parser *parser,
struct nl_pstate *npt, void *target)
{
+ if (__predict_false(hdr->nlmsg_len - sizeof(struct nlmsghdr) <
+ parser->nl_hdr_off) &&
+ ((hdr = nl_alloc_compat_hdr(hdr, parser->nl_hdr_off, npt)) == NULL))
+ return (ENOMEM);
return (nl_parse_header(hdr + 1, hdr->nlmsg_len - sizeof(*hdr), parser,
npt, target));
}
diff --git a/sys/netlink/netlink_message_parser.c b/sys/netlink/netlink_message_parser.c
--- a/sys/netlink/netlink_message_parser.c
+++ b/sys/netlink/netlink_message_parser.c
@@ -50,6 +50,38 @@
#include <netlink/netlink_debug.h>
_DECLARE_DEBUG(LOG_INFO);
+/*
+ * Some applications try to provide only the non-zero part of the required
+ * message header instead of a full one. It happens when fetching routes or
+ * interface addresses, where the first header byte is the family.
+ * This behavior is "illegal" under the "strict" Netlink socket option, however
+ * there are many applications out there doing things in the "old" way.
+ * Support this usecase by copying the provided bytes into the temporary
+ * zero-filled header and running the parser on this header instead.
+ */
+struct nlmsghdr *
+nl_alloc_compat_hdr(struct nlmsghdr *hdr, uint32_t len, struct nl_pstate *npt)
+{
+ struct nlmsghdr *tmp;
+
+ MPASS(hdr->nlmsg_len < sizeof(struct nlmsghdr) + len);
+
+ len += sizeof(struct nlmsghdr);
+ if (npt->strict) {
+ nlmsg_report_err_msg(npt,
+ "header too short: expected %d, got %d",
+ len, hdr->nlmsg_len);
+ return (NULL);
+ }
+ tmp = npt_alloc(npt, len);
+ if (tmp == NULL)
+ return (NULL);
+ memcpy(tmp, hdr, hdr->nlmsg_len);
+ tmp->nlmsg_len = len;
+
+ return (tmp);
+}
+
bool
nlmsg_report_err_msg(struct nl_pstate *npt, const char *fmt, ...)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, May 22, 6:52 AM (16 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32905835
Default Alt Text
D56915.diff (2 KB)
Attached To
Mode
D56915: netlink: factor out compatibility code from inlined function
Attached
Detach File
Event Timeline
Log In to Comment