free(events);
 }
 
+static bool perf_attr_check(struct perf_event_attr *attr)
+{
+       if (attr->__reserved_1 || attr->__reserved_2 || attr->__reserved_3) {
+               pr_warning("Reserved bits are set unexpectedly. "
+                          "Please update perf tool.\n");
+               return false;
+       }
+
+       if (attr->sample_type & ~(PERF_SAMPLE_MAX-1)) {
+               pr_warning("Unknown sample type (0x%llx) is detected. "
+                          "Please update perf tool.\n",
+                          attr->sample_type);
+               return false;
+       }
+
+       if (attr->read_format & ~(PERF_FORMAT_MAX-1)) {
+               pr_warning("Unknown read format (0x%llx) is detected. "
+                          "Please update perf tool.\n",
+                          attr->read_format);
+               return false;
+       }
+
+       if ((attr->sample_type & PERF_SAMPLE_BRANCH_STACK) &&
+           (attr->branch_sample_type & ~(PERF_SAMPLE_BRANCH_MAX-1))) {
+               pr_warning("Unknown branch sample type (0x%llx) is detected. "
+                          "Please update perf tool.\n",
+                          attr->branch_sample_type);
+
+               return false;
+       }
+
+       return true;
+}
+
 static struct evsel *read_event_desc(struct feat_fd *ff)
 {
        struct evsel *evsel, *events = NULL;
 
                memcpy(&evsel->core.attr, buf, msz);
 
+               if (!perf_attr_check(&evsel->core.attr))
+                       goto error;
+
                if (do_read_u32(ff, &nr))
                        goto error;