Make the datapath tolerate kernels that lack NLA_NUL_STRING.
authorBen Pfaff <blp@nicira.com>
Wed, 31 Dec 2008 18:35:42 +0000 (10:35 -0800)
committerBen Pfaff <blp@nicira.com>
Wed, 31 Dec 2008 18:36:32 +0000 (10:36 -0800)
NLA_NUL_STRING was introduced in 2.6.19.

acinclude.m4
datapath/datapath.c
datapath/linux-2.4/compat-2.4/include/net/netlink.h
datapath/linux-2.6/compat-2.6/include/net/netlink.h [new file with mode: 0644]

index 1380940efb587bd85d925d32f3dca6eee7a0069c..1017ff7e458ea14a9285ad30306a60cd68346b04 100644 (file)
@@ -109,6 +109,8 @@ AC_DEFUN([OFP_CHECK_LINUX26_COMPAT], [
                   [OFP_DEFINE([HAVE_SKBUFF_HEADER_HELPERS])])
   OFP_GREP_IFELSE([$KSRC26/include/linux/skbuff.h], [raw],
                   [OFP_DEFINE([HAVE_MAC_RAW])])
+  OFP_GREP_IFELSE([$KSRC26/include/net/netlink.h], [NLA_NUL_STRING],
+                  [OFP_DEFINE([HAVE_NLA_NUL_STRING])])
   if cmp -s datapath/linux-2.6/kcompat.h.new \
             datapath/linux-2.6/kcompat.h >/dev/null 2>&1; then
     rm datapath/linux-2.6/kcompat.h.new
index 286c4c02aeed6b26d8af531db5eae7ba784133c9..d6f5c2594c6012a762b02e500a7368498f51098e 100644 (file)
@@ -1116,6 +1116,9 @@ static int dp_genl_add(struct sk_buff *skb, struct genl_info *info)
        const char *dp_name = info->attrs[DP_GENL_A_DP_NAME] ?
                        nla_data(info->attrs[DP_GENL_A_DP_NAME]) : NULL;
 
+       if (VERIFY_NUL_STRING(info->attrs[DP_GENL_A_DP_NAME]))
+               return -EINVAL;
+
        if ((dp_idx == -1) && (!dp_name))
                return -EINVAL;
 
@@ -1157,6 +1160,9 @@ lookup_dp(struct genl_info *info)
        const char *dp_name = info->attrs[DP_GENL_A_DP_NAME] ?
                        nla_data(info->attrs[DP_GENL_A_DP_NAME]) : NULL;
 
+       if (VERIFY_NUL_STRING(info->attrs[DP_GENL_A_DP_NAME]))
+               return ERR_PTR(-EINVAL);
+
        if (dp_idx != -1) {
                struct datapath *dp = dp_get_by_idx(dp_idx);
                if (!dp)
@@ -1260,7 +1266,8 @@ static int dp_genl_add_del_port(struct sk_buff *skb, struct genl_info *info)
        struct net_device *port;
        int err;
 
-       if (!info->attrs[DP_GENL_A_PORTNAME])
+       if (!info->attrs[DP_GENL_A_PORTNAME] ||
+           VERIFY_NUL_STRING(info->attrs[DP_GENL_A_PORTNAME]))
                return -EINVAL;
 
        /* Get datapath. */
index 46cdafd9315ca7a42260c882c661b66d5b8fbe2b..f4e3155ba807cb33344f112440ac87252bd48429 100644 (file)
@@ -1011,4 +1011,9 @@ static inline int nla_validate_nested(struct nlattr *start, int maxtype,
 #define nla_for_each_nested(pos, nla, rem) \
        nla_for_each_attr(pos, nla_data(nla), nla_len(nla), rem)
 
+static inline int VERIFY_NUL_STRING(struct nlattr *attr)
+{
+       return 0;
+}
+
 #endif
diff --git a/datapath/linux-2.6/compat-2.6/include/net/netlink.h b/datapath/linux-2.6/compat-2.6/include/net/netlink.h
new file mode 100644 (file)
index 0000000..0be5315
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __NET_NETLINK_WRAPPER_H
+#define __NET_NETLINK_WRAPPER_H 1
+
+#include_next <net/netlink.h>
+
+#ifndef HAVE_NLA_NUL_STRING
+#define NLA_NUL_STRING NLA_STRING
+
+static inline int VERIFY_NUL_STRING(struct nlattr *attr)
+{
+       return (!attr || (nla_len(attr)
+                         && memchr(nla_data(attr), '0', nla_len(attr)))
+               ? 0 : EINVAL);
+}
+#else
+static inline int VERIFY_NUL_STRING(struct nlattr *attr)
+{
+       return 0;
+}
+#endif /* !HAVE_NLA_NUL_STRING */
+
+#endif /* net/netlink.h */