diff options
author | Greg Hackmann <ghackmann@google.com> | 2016-02-19 15:04:23 -0800 |
---|---|---|
committer | Winnie Hsu <whsu@nvidia.com> | 2017-05-16 12:38:09 -0700 |
commit | 36d071c93e79a3b340aa76c83079cdf441b5d381 (patch) | |
tree | 1c2d01f8f82d693838563312318f5bb5269cb952 /drivers | |
parent | 651cce8f33cff889007ca563cdcff98abe3a5e90 (diff) |
tegra: camera: validate PCLLK_IOCTL_SEQ_XX params
The driver expects the userspace-provided table to be terminated with
addr == CAMERA_TABLE_END. Reject tables that aren't.
(back ported from Nexus N9 project)
Bug 1832830
Change-Id: Id1e168e02fbf323d094fe8c36c6e4bd90cceee4f
Signed-off-by: Greg Hackmann <ghackmann@google.com>
Reviewed-on: http://git-master/r/1271368
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Frank Chen <frankc@nvidia.com>
Tested-by: Frank Chen <frankc@nvidia.com>
Reviewed-by: Jihoon Bang <jbang@nvidia.com>
Reviewed-by: Winnie Hsu <whsu@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/platform/tegra/camera.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/media/platform/tegra/camera.c b/drivers/media/platform/tegra/camera.c index f54a3c01d38d..a8bba03708f1 100644 --- a/drivers/media/platform/tegra/camera.c +++ b/drivers/media/platform/tegra/camera.c @@ -178,6 +178,20 @@ int __camera_get_params( return 0; } +static int camera_validate_p_i2c_table(struct camera_info *cam, + const struct nvc_param *params, + const struct camera_reg *p_i2c_table, const char *caller) +{ + u32 idx, last_idx = params->sizeofvalue / sizeof(p_i2c_table[0]); + + for (idx = 0; idx < last_idx; idx++) + if (p_i2c_table[idx].addr == CAMERA_TABLE_END) + return 0; + + dev_err(cam->dev, "%s: table is not properly terminated\n", caller); + return -EINVAL; +} + static int camera_seq_rd(struct camera_info *cam, unsigned long arg) { struct nvc_param params; @@ -189,6 +203,10 @@ static int camera_seq_rd(struct camera_info *cam, unsigned long arg) if (err) return err; + err = camera_validate_p_i2c_table(cam, ¶ms, p_i2c_table, __func__); + if (err) + goto seq_rd_end; + err = camera_dev_rd_table(cam->cdev, p_i2c_table); if (!err && copy_to_user(MAKE_USER_PTR(params.p_value), p_i2c_table, params.sizeofvalue)) { @@ -197,6 +215,7 @@ static int camera_seq_rd(struct camera_info *cam, unsigned long arg) err = -EINVAL; } +seq_rd_end: kfree(p_i2c_table); return err; } @@ -251,6 +270,10 @@ static int camera_seq_wr(struct camera_info *cam, unsigned long arg) goto seq_wr_end; } + err = camera_validate_p_i2c_table(cam, ¶ms, p_i2c_table, __func__); + if (err) + goto seq_wr_end; + switch (params.param) { case CAMERA_SEQ_REGISTER_EXEC: case CAMERA_SEQ_REGISTER_ONLY: |