summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hackmann <ghackmann@google.com>2016-02-19 15:04:23 -0800
committerWinnie Hsu <whsu@nvidia.com>2017-05-16 12:38:09 -0700
commit36d071c93e79a3b340aa76c83079cdf441b5d381 (patch)
tree1c2d01f8f82d693838563312318f5bb5269cb952
parent651cce8f33cff889007ca563cdcff98abe3a5e90 (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>
-rw-r--r--drivers/media/platform/tegra/camera.c23
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, &params, 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, &params, p_i2c_table, __func__);
+ if (err)
+ goto seq_wr_end;
+
switch (params.param) {
case CAMERA_SEQ_REGISTER_EXEC:
case CAMERA_SEQ_REGISTER_ONLY: