diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2012-05-31 08:15:28 +0300 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-06-03 08:01:37 -0700 |
commit | fdf40891983fc3fe1942877dcb07a4eab25f1796 (patch) | |
tree | f95b2e3f593cece2d8bd89c7cef8489f9fc42d6e /drivers/video/tegra/host/bus_client.c | |
parent | 22049ebd104af134fce3cdf39c813fb993d869e9 (diff) |
video: tegra: host: Restrict register access
Register access (read/write) to modules MPE, ISP and VI lack sanity
check for the register number. Add checks to ensure only aperture is
accessed. Also make sure that the check accounts for wrapping of
values of offset and count.
Also fixes the register offset for reads which are done in multiple
blocks.
Bug 992938
Change-Id: I35f30cbd1dda31956286e48c5995b24fd262d1ae
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/105585
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/video/tegra/host/bus_client.c')
-rw-r--r-- | drivers/video/tegra/host/bus_client.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c index 962de32f359f..651a8dec738c 100644 --- a/drivers/video/tegra/host/bus_client.c +++ b/drivers/video/tegra/host/bus_client.c @@ -50,10 +50,28 @@ #include "nvhost_job.h" #include "nvhost_hwctx.h" -void nvhost_read_module_regs(struct nvhost_device *ndev, +static int validate_reg(struct nvhost_device *ndev, u32 offset, int count) +{ + struct resource *r = nvhost_get_resource(ndev, IORESOURCE_MEM, 0); + int err = 0; + + if (offset + 4 * count > resource_size(r) + || (offset + 4 * count < offset)) + err = -EPERM; + + return err; +} + +int nvhost_read_module_regs(struct nvhost_device *ndev, u32 offset, int count, u32 *values) { void __iomem *p = ndev->aperture + offset; + int err; + + /* verify offset */ + err = validate_reg(ndev, offset, count); + if (err) + return err; nvhost_module_busy(ndev); while (count--) { @@ -62,12 +80,20 @@ void nvhost_read_module_regs(struct nvhost_device *ndev, } rmb(); nvhost_module_idle(ndev); + + return 0; } -void nvhost_write_module_regs(struct nvhost_device *ndev, +int nvhost_write_module_regs(struct nvhost_device *ndev, u32 offset, int count, const u32 *values) { void __iomem *p = ndev->aperture + offset; + int err; + + /* verify offset */ + err = validate_reg(ndev, offset, count); + if (err) + return err; nvhost_module_busy(ndev); while (count--) { @@ -76,6 +102,8 @@ void nvhost_write_module_regs(struct nvhost_device *ndev, } wmb(); nvhost_module_idle(ndev); + + return 0; } struct nvhost_channel_userctx { |