[CRIU] [PATCH] libnetlink: back port a fix for nlattr_parse()
Andrey Vagin
avagin at openvz.org
Tue Mar 15 22:06:17 PDT 2016
From: Andrew Vagin <avagin at virtuozzo.com>
The bug was fixed in libnl-3 3.2.24, but
rhel7 and the Trusty ubuntu don't update this packet yet
commit b50a36bf34e7452377ab9bbb4d1873b68c65bf72
Author: Samuel Gauthier <samuel.gauthier at 6wind.com>
Date: Fri Nov 29 09:28:44 2013 +0100
The commit 6a8d90f5fec4 "attr: Allow attribute type 0" intended to
allow the parsing of {netlink,packet,unix}_diag, even if they are
using type 0 for valid attributes.
It lacked this part in nla_parse.
Cc: Nicolas Dichtel <nicolas.dichtel at 6wind.com>
Signed-off-by: Samuel Gauthier <samuel.gauthier at 6wind.com>
Signed-off-by: Thomas Graf <tgraf at suug.ch>
https://github.com/xemul/criu/issues/137
Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
criu/Makefile | 4 ++++
criu/libnetlink.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 76 insertions(+)
diff --git a/criu/Makefile b/criu/Makefile
index 575d7e4..25d75df 100644
--- a/criu/Makefile
+++ b/criu/Makefile
@@ -6,6 +6,10 @@ HOSTLD ?= ld
HOSTCFLAGS ?= $(CFLAGS)
CFLAGS += $(USERCFLAGS)
+# here is a workaround for a bug in libnl-3:
+# 6a8d90f5fec4 "attr: Allow attribute type 0"
+LDFLAGS += -Wl,--wrap=nla_parse,--wrap=nlmsg_parse
+
export HOSTCC HOSTLD HOSTCFLAGS
ifeq ($(ARCH),x86)
diff --git a/criu/libnetlink.c b/criu/libnetlink.c
index 4a651cb..5f69a3d 100644
--- a/criu/libnetlink.c
+++ b/criu/libnetlink.c
@@ -3,6 +3,7 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <libnl3/netlink/attr.h>
+#include <libnl3/netlink/msg.h>
#include <string.h>
#include <unistd.h>
@@ -146,3 +147,74 @@ int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
return 0;
}
+
+/*
+ * Here is a workaround for a bug in libnl-3:
+ * 6a8d90f5fec4 "attr: Allow attribute type 0
+ */
+
+/**
+ * Create attribute index based on a stream of attributes.
+ * @arg tb Index array to be filled (maxtype+1 elements).
+ * @arg maxtype Maximum attribute type expected and accepted.
+ * @arg head Head of attribute stream.
+ * @arg len Length of attribute stream.
+ * @arg policy Attribute validation policy.
+ *
+ * Iterates over the stream of attributes and stores a pointer to each
+ * attribute in the index array using the attribute type as index to
+ * the array. Attribute with a type greater than the maximum type
+ * specified will be silently ignored in order to maintain backwards
+ * compatibility. If \a policy is not NULL, the attribute will be
+ * validated using the specified policy.
+ *
+ * @see nla_validate
+ * @return 0 on success or a negative error code.
+ */
+int __wrap_nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
+ struct nla_policy *policy)
+{
+ struct nlattr *nla;
+ int rem;
+
+ memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
+
+ nla_for_each_attr(nla, head, len, rem) {
+ int type = nla_type(nla);
+
+ if (type > maxtype)
+ continue;
+
+ if (tb[type])
+ pr_warn("Attribute of type %#x found multiple times in message, "
+ "previous attribute is being ignored.\n", type);
+
+ tb[type] = nla;
+ }
+
+ if (rem > 0)
+ pr_warn("netlink: %d bytes leftover after parsing "
+ "attributes.\n", rem);
+
+ return 0;
+}
+
+/**
+ * parse attributes of a netlink message
+ * @arg nlh netlink message header
+ * @arg hdrlen length of family specific header
+ * @arg tb destination array with maxtype+1 elements
+ * @arg maxtype maximum attribute type to be expected
+ * @arg policy validation policy
+ *
+ * See nla_parse()
+ */
+int __wrap_nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
+ int maxtype, struct nla_policy *policy)
+{
+ if (!nlmsg_valid_hdr(nlh, hdrlen))
+ return -NLE_MSG_TOOSHORT;
+
+ return nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen),
+ nlmsg_attrlen(nlh, hdrlen), policy);
+}
--
2.5.0
More information about the CRIU
mailing list