x86/intel_rdt: Return error for incorrect resource names in schemata
authorVikas Shivappa <vikas.shivappa@linux.intel.com>
Wed, 19 Apr 2017 23:50:04 +0000 (16:50 -0700)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 20 Apr 2017 13:57:59 +0000 (15:57 +0200)
When schemata parses the resource names it does not return an error if it
detects incorrect resource names and fails quietly.

This happens because for_each_enabled_rdt_resource(r) leaves "r" pointing
beyond the end of the rdt_resources_all[] array, and the check for !r->name
results in an out of bounds access.

Split the resource parsing part into a helper function to avoid the issue.

[ tglx: Made it readable by splitting the parser loop out into a function ]

Reported-by: Prakhya, Sai Praneeth <sai.praneeth.prakhya@intel.com>
Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
Tested-by: Prakhya, Sai Praneeth <sai.praneeth.prakhya@intel.com>
Cc: fenghua.yu@intel.com
Cc: tony.luck@intel.com
Cc: ravi.v.shankar@intel.com
Cc: vikas.shivappa@intel.com
Link: http://lkml.kernel.org/r/1492645804-17465-4-git-send-email-vikas.shivappa@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/kernel/cpu/intel_rdt_schemata.c

index e64b2cf1c428b17c6bca7d306f405c6f852b0ff5..406d7a6532f98c586164cd8115edb1912581b82a 100644 (file)
@@ -188,6 +188,17 @@ done:
        return 0;
 }
 
+static int rdtgroup_parse_resource(char *resname, char *tok, int closid)
+{
+       struct rdt_resource *r;
+
+       for_each_enabled_rdt_resource(r) {
+               if (!strcmp(resname, r->name) && closid < r->num_closid)
+                       return parse_line(tok, r);
+       }
+       return -EINVAL;
+}
+
 ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
                                char *buf, size_t nbytes, loff_t off)
 {
@@ -210,9 +221,10 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
 
        closid = rdtgrp->closid;
 
-       for_each_enabled_rdt_resource(r)
+       for_each_enabled_rdt_resource(r) {
                list_for_each_entry(dom, &r->domains, list)
                        dom->have_new_ctrl = false;
+       }
 
        while ((tok = strsep(&buf, "\n")) != NULL) {
                resname = strim(strsep(&tok, ":"));
@@ -220,19 +232,9 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
                        ret = -EINVAL;
                        goto out;
                }
-               for_each_enabled_rdt_resource(r) {
-                       if (!strcmp(resname, r->name) &&
-                           closid < r->num_closid) {
-                               ret = parse_line(tok, r);
-                               if (ret)
-                                       goto out;
-                               break;
-                       }
-               }
-               if (!r->name) {
-                       ret = -EINVAL;
+               ret = rdtgroup_parse_resource(resname, tok, closid);
+               if (ret)
                        goto out;
-               }
        }
 
        for_each_enabled_rdt_resource(r) {