datapath: Disallow unknown attributes on OVS_ACTION_ATTR_SAMPLE action.
authorBen Pfaff <blp@nicira.com>
Mon, 24 Oct 2011 17:40:52 +0000 (10:40 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 24 Oct 2011 18:22:01 +0000 (11:22 -0700)
Bug #7932.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
datapath/datapath.c

index 11a2a110514c3b7cd714181df0fb32e341f276cd..7bad8d0ffd9bee7aed35922806860a78f559210f 100644 (file)
@@ -512,24 +512,29 @@ static int validate_actions(const struct nlattr *attr,
 static int validate_sample(const struct nlattr *attr,
                                const struct sw_flow_key *key, int depth)
 {
-       static const struct nla_policy sample_policy[OVS_SAMPLE_ATTR_MAX + 1] =
-       {
-               [OVS_SAMPLE_ATTR_PROBABILITY] = {.type = NLA_U32 },
-               [OVS_SAMPLE_ATTR_ACTIONS] = {.type = NLA_UNSPEC },
-       };
-       struct nlattr *a[OVS_SAMPLE_ATTR_MAX + 1];
-       int error;
-
-       error = nla_parse_nested(a, OVS_SAMPLE_ATTR_MAX, attr, sample_policy);
-       if (error)
-               return error;
+       const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1];
+       const struct nlattr *probability, *actions;
+       const struct nlattr *a;
+       int rem;
 
-       if (!a[OVS_SAMPLE_ATTR_PROBABILITY])
+       memset(attrs, 0, sizeof(attrs));
+       nla_for_each_nested (a, attr, rem) {
+               int type = nla_type(a);
+               if (!type || type > OVS_SAMPLE_ATTR_MAX || attrs[type])
+                       return -EINVAL;
+               attrs[type] = a;
+       }
+       if (rem)
                return -EINVAL;
-       if (!a[OVS_SAMPLE_ATTR_ACTIONS])
+
+       probability = attrs[OVS_SAMPLE_ATTR_PROBABILITY];
+       if (!probability || nla_len(probability) != sizeof(u32))
                return -EINVAL;
 
-       return validate_actions(a[OVS_SAMPLE_ATTR_ACTIONS], key, (depth + 1));
+       actions = attrs[OVS_SAMPLE_ATTR_ACTIONS];
+       if (!actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN))
+               return -EINVAL;
+       return validate_actions(actions, key, depth + 1);
 }
 
 static int validate_action_key(const struct nlattr *a,