diff options
author | Mathieu Poirier <mathieu.poirier@linaro.org> | 2018-07-11 15:40:12 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-07-15 07:52:56 -0400 |
commit | 450367f06ef310af15f6424376ce9d5c7879c2d1 (patch) | |
tree | 0270fcdcbbbb34cd603b0af8df7fe3922661fd3e /drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | |
parent | 7bd50ccf001f77db236af51797579359b09e2354 (diff) |
coresight: etm4x: Don't use contextID with PID namespaces
As with ETM3x, the ETM4x tracers can trigger trace acquisition based on
contextID value, something that isn't useful when PID namespaces are
enabled. Indeed the PID value of a process has a different representation
in the kernel and the PID namespace, making the feature confusing and
potentially leaking internal kernel information.
As such simply return an error when the feature is being used from a
PID namespace other than the default one.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Kim Phillips <kim.phillips@arm.com>
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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 @@ | |||
4 | * Author: Mathieu Poirier <mathieu.poirier@linaro.org> | 4 | * Author: Mathieu Poirier <mathieu.poirier@linaro.org> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/pid_namespace.h> | ||
7 | #include <linux/pm_runtime.h> | 8 | #include <linux/pm_runtime.h> |
8 | #include <linux/sysfs.h> | 9 | #include <linux/sysfs.h> |
9 | #include "coresight-etm4x.h" | 10 | #include "coresight-etm4x.h" |
@@ -250,10 +251,8 @@ static ssize_t reset_store(struct device *dev, | |||
250 | } | 251 | } |
251 | 252 | ||
252 | config->ctxid_idx = 0x0; | 253 | config->ctxid_idx = 0x0; |
253 | for (i = 0; i < drvdata->numcidc; i++) { | 254 | for (i = 0; i < drvdata->numcidc; i++) |
254 | config->ctxid_pid[i] = 0x0; | 255 | config->ctxid_pid[i] = 0x0; |
255 | config->ctxid_vpid[i] = 0x0; | ||
256 | } | ||
257 | 256 | ||
258 | config->ctxid_mask0 = 0x0; | 257 | config->ctxid_mask0 = 0x0; |
259 | config->ctxid_mask1 = 0x0; | 258 | config->ctxid_mask1 = 0x0; |
@@ -1637,9 +1636,16 @@ static ssize_t ctxid_pid_show(struct device *dev, | |||
1637 | struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); | 1636 | struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); |
1638 | struct etmv4_config *config = &drvdata->config; | 1637 | struct etmv4_config *config = &drvdata->config; |
1639 | 1638 | ||
1639 | /* | ||
1640 | * Don't use contextID tracing if coming from a PID namespace. See | ||
1641 | * comment in ctxid_pid_store(). | ||
1642 | */ | ||
1643 | if (task_active_pid_ns(current) != &init_pid_ns) | ||
1644 | return -EINVAL; | ||
1645 | |||
1640 | spin_lock(&drvdata->spinlock); | 1646 | spin_lock(&drvdata->spinlock); |
1641 | idx = config->ctxid_idx; | 1647 | idx = config->ctxid_idx; |
1642 | val = (unsigned long)config->ctxid_vpid[idx]; | 1648 | val = (unsigned long)config->ctxid_pid[idx]; |
1643 | spin_unlock(&drvdata->spinlock); | 1649 | spin_unlock(&drvdata->spinlock); |
1644 | return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); | 1650 | return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); |
1645 | } | 1651 | } |
@@ -1649,26 +1655,35 @@ static ssize_t ctxid_pid_store(struct device *dev, | |||
1649 | const char *buf, size_t size) | 1655 | const char *buf, size_t size) |
1650 | { | 1656 | { |
1651 | u8 idx; | 1657 | u8 idx; |
1652 | unsigned long vpid, pid; | 1658 | unsigned long pid; |
1653 | struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); | 1659 | struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); |
1654 | struct etmv4_config *config = &drvdata->config; | 1660 | struct etmv4_config *config = &drvdata->config; |
1655 | 1661 | ||
1656 | /* | 1662 | /* |
1663 | * When contextID tracing is enabled the tracers will insert the | ||
1664 | * value found in the contextID register in the trace stream. But if | ||
1665 | * a process is in a namespace the PID of that process as seen from the | ||
1666 | * namespace won't be what the kernel sees, something that makes the | ||
1667 | * feature confusing and can potentially leak kernel only information. | ||
1668 | * As such refuse to use the feature if @current is not in the initial | ||
1669 | * PID namespace. | ||
1670 | */ | ||
1671 | if (task_active_pid_ns(current) != &init_pid_ns) | ||
1672 | return -EINVAL; | ||
1673 | |||
1674 | /* | ||
1657 | * only implemented when ctxid tracing is enabled, i.e. at least one | 1675 | * only implemented when ctxid tracing is enabled, i.e. at least one |
1658 | * ctxid comparator is implemented and ctxid is greater than 0 bits | 1676 | * ctxid comparator is implemented and ctxid is greater than 0 bits |
1659 | * in length | 1677 | * in length |
1660 | */ | 1678 | */ |
1661 | if (!drvdata->ctxid_size || !drvdata->numcidc) | 1679 | if (!drvdata->ctxid_size || !drvdata->numcidc) |
1662 | return -EINVAL; | 1680 | return -EINVAL; |
1663 | if (kstrtoul(buf, 16, &vpid)) | 1681 | if (kstrtoul(buf, 16, &pid)) |
1664 | return -EINVAL; | 1682 | return -EINVAL; |
1665 | 1683 | ||
1666 | pid = coresight_vpid_to_pid(vpid); | ||
1667 | |||
1668 | spin_lock(&drvdata->spinlock); | 1684 | spin_lock(&drvdata->spinlock); |
1669 | idx = config->ctxid_idx; | 1685 | idx = config->ctxid_idx; |
1670 | config->ctxid_pid[idx] = (u64)pid; | 1686 | config->ctxid_pid[idx] = (u64)pid; |
1671 | config->ctxid_vpid[idx] = (u64)vpid; | ||
1672 | spin_unlock(&drvdata->spinlock); | 1687 | spin_unlock(&drvdata->spinlock); |
1673 | return size; | 1688 | return size; |
1674 | } | 1689 | } |
@@ -1682,6 +1697,13 @@ static ssize_t ctxid_masks_show(struct device *dev, | |||
1682 | struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); | 1697 | struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); |
1683 | struct etmv4_config *config = &drvdata->config; | 1698 | struct etmv4_config *config = &drvdata->config; |
1684 | 1699 | ||
1700 | /* | ||
1701 | * Don't use contextID tracing if coming from a PID namespace. See | ||
1702 | * comment in ctxid_pid_store(). | ||
1703 | */ | ||
1704 | if (task_active_pid_ns(current) != &init_pid_ns) | ||
1705 | return -EINVAL; | ||
1706 | |||
1685 | spin_lock(&drvdata->spinlock); | 1707 | spin_lock(&drvdata->spinlock); |
1686 | val1 = config->ctxid_mask0; | 1708 | val1 = config->ctxid_mask0; |
1687 | val2 = config->ctxid_mask1; | 1709 | val2 = config->ctxid_mask1; |
@@ -1699,6 +1721,13 @@ static ssize_t ctxid_masks_store(struct device *dev, | |||
1699 | struct etmv4_config *config = &drvdata->config; | 1721 | struct etmv4_config *config = &drvdata->config; |
1700 | 1722 | ||
1701 | /* | 1723 | /* |
1724 | * Don't use contextID tracing if coming from a PID namespace. See | ||
1725 | * comment in ctxid_pid_store(). | ||
1726 | */ | ||
1727 | if (task_active_pid_ns(current) != &init_pid_ns) | ||
1728 | return -EINVAL; | ||
1729 | |||
1730 | /* | ||
1702 | * only implemented when ctxid tracing is enabled, i.e. at least one | 1731 | * only implemented when ctxid tracing is enabled, i.e. at least one |
1703 | * ctxid comparator is implemented and ctxid is greater than 0 bits | 1732 | * ctxid comparator is implemented and ctxid is greater than 0 bits |
1704 | * in length | 1733 | * in length |