diff options
Diffstat (limited to 'drivers/hwtracing/coresight/coresight-etm4x-sysfs.c')
-rw-r--r-- | drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c index 4eb8da785ce0..a0365e23678e 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -4,6 +4,7 @@ * Author: Mathieu Poirier <mathieu.poirier@linaro.org> */ +#include <linux/pid_namespace.h> #include <linux/pm_runtime.h> #include <linux/sysfs.h> #include "coresight-etm4x.h" @@ -250,10 +251,8 @@ static ssize_t reset_store(struct device *dev, } config->ctxid_idx = 0x0; - for (i = 0; i < drvdata->numcidc; i++) { + for (i = 0; i < drvdata->numcidc; i++) config->ctxid_pid[i] = 0x0; - config->ctxid_vpid[i] = 0x0; - } config->ctxid_mask0 = 0x0; config->ctxid_mask1 = 0x0; @@ -1637,9 +1636,16 @@ static ssize_t ctxid_pid_show(struct device *dev, struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); struct etmv4_config *config = &drvdata->config; + /* + * Don't use contextID tracing if coming from a PID namespace. See + * comment in ctxid_pid_store(). + */ + if (task_active_pid_ns(current) != &init_pid_ns) + return -EINVAL; + spin_lock(&drvdata->spinlock); idx = config->ctxid_idx; - val = (unsigned long)config->ctxid_vpid[idx]; + val = (unsigned long)config->ctxid_pid[idx]; spin_unlock(&drvdata->spinlock); return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); } @@ -1649,26 +1655,35 @@ static ssize_t ctxid_pid_store(struct device *dev, const char *buf, size_t size) { u8 idx; - unsigned long vpid, pid; + unsigned long pid; struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); struct etmv4_config *config = &drvdata->config; /* + * When contextID tracing is enabled the tracers will insert the + * value found in the contextID register in the trace stream. But if + * a process is in a namespace the PID of that process as seen from the + * namespace won't be what the kernel sees, something that makes the + * feature confusing and can potentially leak kernel only information. + * As such refuse to use the feature if @current is not in the initial + * PID namespace. + */ + if (task_active_pid_ns(current) != &init_pid_ns) + return -EINVAL; + + /* * only implemented when ctxid tracing is enabled, i.e. at least one * ctxid comparator is implemented and ctxid is greater than 0 bits * in length */ if (!drvdata->ctxid_size || !drvdata->numcidc) return -EINVAL; - if (kstrtoul(buf, 16, &vpid)) + if (kstrtoul(buf, 16, &pid)) return -EINVAL; - pid = coresight_vpid_to_pid(vpid); - spin_lock(&drvdata->spinlock); idx = config->ctxid_idx; config->ctxid_pid[idx] = (u64)pid; - config->ctxid_vpid[idx] = (u64)vpid; spin_unlock(&drvdata->spinlock); return size; } @@ -1682,6 +1697,13 @@ static ssize_t ctxid_masks_show(struct device *dev, struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); struct etmv4_config *config = &drvdata->config; + /* + * Don't use contextID tracing if coming from a PID namespace. See + * comment in ctxid_pid_store(). + */ + if (task_active_pid_ns(current) != &init_pid_ns) + return -EINVAL; + spin_lock(&drvdata->spinlock); val1 = config->ctxid_mask0; val2 = config->ctxid_mask1; @@ -1699,6 +1721,13 @@ static ssize_t ctxid_masks_store(struct device *dev, struct etmv4_config *config = &drvdata->config; /* + * Don't use contextID tracing if coming from a PID namespace. See + * comment in ctxid_pid_store(). + */ + if (task_active_pid_ns(current) != &init_pid_ns) + return -EINVAL; + + /* * only implemented when ctxid tracing is enabled, i.e. at least one * ctxid comparator is implemented and ctxid is greater than 0 bits * in length |