All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] atomisp set_fs() fix
@ 2020-06-04 16:16 Sakari Ailus
  2020-06-04 16:16 ` [PATCH 1/4] staging: atomisp: There's no struct atomisp_dvs2_coefficients Sakari Ailus
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Sakari Ailus @ 2020-06-04 16:16 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media

Hi Mauro,

This set addresses the atomisp IOCTL handling security issues using the
same approach chosen for V4L2. I've rebased them on the current driver in
staging.

Sakari Ailus (4):
  staging: atomisp: There's no struct atomisp_dvs2_coefficients
  staging: atomisp: Fix atomisp_overlay32 compat handling
  staging: atomisp: Fix compat IOCTL handling
  staging: atomisp: Check return value from compat_alloc_user_space

 .../media/atomisp/include/linux/atomisp.h     |   2 +-
 .../staging/media/atomisp/pci/atomisp_cmd.c   |   2 +-
 .../media/atomisp/pci/atomisp_compat_css20.c  |   4 +-
 .../atomisp/pci/atomisp_compat_ioctl32.c      | 934 +++++++++---------
 4 files changed, 477 insertions(+), 465 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] staging: atomisp: There's no struct atomisp_dvs2_coefficients
  2020-06-04 16:16 [PATCH 0/4] atomisp set_fs() fix Sakari Ailus
@ 2020-06-04 16:16 ` Sakari Ailus
  2020-06-04 16:16 ` [PATCH 2/4] staging: atomisp: Fix atomisp_overlay32 compat handling Sakari Ailus
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sakari Ailus @ 2020-06-04 16:16 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media

It's called struct atomisp_dis_coefficients.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/staging/media/atomisp/include/linux/atomisp.h    | 2 +-
 drivers/staging/media/atomisp/pci/atomisp_cmd.c          | 2 +-
 drivers/staging/media/atomisp/pci/atomisp_compat_css20.c | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
index e9670749bae08..bf262de1eab82 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
@@ -509,7 +509,7 @@ struct atomisp_parameters {
 	struct atomisp_shading_table *shading_table;
 	struct atomisp_morph_table   *morph_table;
 	struct atomisp_dvs_coefficients *dvs_coefs; /* DVS 1.0 coefficients */
-	struct atomisp_dvs2_coefficients *dvs2_coefs; /* DVS 2.0 coefficients */
+	struct atomisp_dis_coefficients *dvs2_coefs; /* DVS 2.0 coefficients */
 	struct atomisp_capture_config   *capture_config;
 	struct atomisp_anr_thres   *anr_thres;
 
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index 5be690f876c11..934fca6102767 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -3796,7 +3796,7 @@ int atomisp_css_cp_dvs2_coefs(struct atomisp_sub_device *asd,
 	}
 
 	css_param->update_flag.dvs2_coefs =
-	    (struct atomisp_dvs2_coefficients *)css_param->dvs2_coeff;
+	    (struct atomisp_dis_coefficients *)css_param->dvs2_coeff;
 	return 0;
 }
 
diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
index 209bc9954a538..c3a7229ccd3d9 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
@@ -3696,8 +3696,8 @@ int atomisp_css_set_dis_coefs(struct atomisp_sub_device *asd,
 		return -EFAULT;
 
 	asd->params.css_param.update_flag.dvs2_coefs =
-	    (struct atomisp_dvs2_coefficients *)
-	    asd->params.css_param.dvs2_coeff;
+		(struct atomisp_dis_coefficients *)
+		asd->params.css_param.dvs2_coeff;
 	/* FIXME! */
 	/*	asd->params.dis_proj_data_valid = false; */
 	asd->params.css_update_params_needed = true;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/4] staging: atomisp: Fix atomisp_overlay32 compat handling
  2020-06-04 16:16 [PATCH 0/4] atomisp set_fs() fix Sakari Ailus
  2020-06-04 16:16 ` [PATCH 1/4] staging: atomisp: There's no struct atomisp_dvs2_coefficients Sakari Ailus
@ 2020-06-04 16:16 ` Sakari Ailus
  2020-06-04 16:16 ` [PATCH 3/4] staging: atomisp: Fix compat IOCTL handling Sakari Ailus
  2020-06-04 16:16 ` [PATCH 4/4] staging: atomisp: Check return value from compat_alloc_user_space Sakari Ailus
  3 siblings, 0 replies; 5+ messages in thread
From: Sakari Ailus @ 2020-06-04 16:16 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media

The struct atomisp_overlay contains overlay_start_x and overlay_start_y
fields. Instead of copying the value of the overlay_start_x field between
the two structs, the value of the overlay_start_y field of the compat
struct was copied to the overlay_start_x field of the 64-bit kernel struct
in get operation and back in put. The overlay_start_x field value was not
copied from or to the user space struct.

Fix this so that the value of overlay_start_x is copied to overlay_start_x
and the value of overlay_start_y is copied to overlay_start_y.

Also do copy blend_overlay_perc_u field only once.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
index 3079043f1fac0..1853d907260db 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
@@ -399,7 +399,8 @@ static int get_atomisp_overlay32(struct atomisp_overlay *kp,
 	    get_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
 	    get_user(kp->blend_overlay_perc_v, &up->blend_overlay_perc_v) ||
 	    get_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
-	    get_user(kp->overlay_start_x, &up->overlay_start_y))
+	    get_user(kp->overlay_start_x, &up->overlay_start_x) ||
+	    get_user(kp->overlay_start_y, &up->overlay_start_y))
 		return -EFAULT;
 
 	kp->frame = (void __force *)compat_ptr(frame);
@@ -423,7 +424,8 @@ static int put_atomisp_overlay32(struct atomisp_overlay *kp,
 	    put_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
 	    put_user(kp->blend_overlay_perc_v, &up->blend_overlay_perc_v) ||
 	    put_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
-	    put_user(kp->overlay_start_x, &up->overlay_start_y))
+	    put_user(kp->overlay_start_x, &up->overlay_start_x)
+	    put_user(kp->overlay_start_y, &up->overlay_start_y))
 		return -EFAULT;
 
 	return 0;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/4] staging: atomisp: Fix compat IOCTL handling
  2020-06-04 16:16 [PATCH 0/4] atomisp set_fs() fix Sakari Ailus
  2020-06-04 16:16 ` [PATCH 1/4] staging: atomisp: There's no struct atomisp_dvs2_coefficients Sakari Ailus
  2020-06-04 16:16 ` [PATCH 2/4] staging: atomisp: Fix atomisp_overlay32 compat handling Sakari Ailus
@ 2020-06-04 16:16 ` Sakari Ailus
  2020-06-04 16:16 ` [PATCH 4/4] staging: atomisp: Check return value from compat_alloc_user_space Sakari Ailus
  3 siblings, 0 replies; 5+ messages in thread
From: Sakari Ailus @ 2020-06-04 16:16 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media

Atomisp compat IOCTL handling suffers from the same security issue than
the V4L2 did. Fix this for atomisp.

See more information in patch a1dfb4c48cc1 ("media: v4l2-compat-ioctl32.c:
refactor compat ioctl32 logic").

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 .../atomisp/pci/atomisp_compat_ioctl32.c      | 934 +++++++++---------
 1 file changed, 471 insertions(+), 463 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
index 1853d907260db..c8649923b6b9e 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
@@ -24,66 +24,61 @@
 #include "atomisp_ioctl.h"
 #include "atomisp_compat_ioctl32.h"
 
-static int get_atomisp_histogram32(struct atomisp_histogram *kp,
+/* Macro borrowed from v4l2-compat-ioctl32.c */
+/* Use the same argument order as copy_in_user */
+#define assign_in_user(to, from)				\
+({								\
+	typeof(*from) __assign_tmp;				\
+								\
+	get_user(__assign_tmp, from) || put_user(__assign_tmp, to);	\
+})
+
+
+static int get_atomisp_histogram32(struct atomisp_histogram __user *kp,
 				   struct atomisp_histogram32 __user *up)
 {
 	compat_uptr_t tmp;
 
 	if (!access_ok(up, sizeof(struct atomisp_histogram32)) ||
-	    get_user(kp->num_elements, &up->num_elements) ||
-	    get_user(tmp, &up->data))
+	    assign_in_user(&kp->num_elements, &up->num_elements) ||
+	    get_user(tmp, &up->data) ||
+	    put_user(compat_ptr(tmp), &kp->data))
 		return -EFAULT;
 
-	kp->data = compat_ptr(tmp);
 	return 0;
 }
 
-static int put_atomisp_histogram32(struct atomisp_histogram *kp,
+static int put_atomisp_histogram32(struct atomisp_histogram __user *kp,
 				   struct atomisp_histogram32 __user *up)
 {
-	compat_uptr_t tmp = (compat_uptr_t)((uintptr_t)kp->data);
+	void __user *tmp;
 
 	if (!access_ok(up, sizeof(struct atomisp_histogram32)) ||
-	    put_user(kp->num_elements, &up->num_elements) ||
-	    put_user(tmp, &up->data))
+	    assign_in_user(&up->num_elements, &kp->num_elements) ||
+	    get_user(tmp, &kp->data) ||
+	    put_user(ptr_to_compat(tmp), &up->data))
 		return -EFAULT;
 
 	return 0;
 }
 
-static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp,
-				      struct v4l2_pix_format __user *up)
-{
-	if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
-		return -EFAULT;
-	return 0;
-}
-
-static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp,
-				      struct v4l2_pix_format __user *up)
-{
-	if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
-		return -EFAULT;
-	return 0;
-}
-
-static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp,
-				  struct v4l2_framebuffer32 __user *up)
+static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
+					struct v4l2_framebuffer32 __user *up)
 {
 	compat_uptr_t tmp;
 
 	if (!access_ok(up, sizeof(struct v4l2_framebuffer32)) ||
 	    get_user(tmp, &up->base) ||
-	    get_user(kp->capability, &up->capability) ||
-	    get_user(kp->flags, &up->flags))
+	    put_user(compat_ptr(tmp), &kp->base) ||
+	    assign_in_user(&kp->capability, &up->capability) ||
+	    assign_in_user(&kp->flags, &up->flags) ||
+	    copy_in_user(&kp->fmt, &up->fmt, sizeof(kp->fmt)))
 		return -EFAULT;
 
-	kp->base = (void __force *)compat_ptr(tmp);
-	get_v4l2_pix_format((struct v4l2_pix_format *)&kp->fmt, &up->fmt);
 	return 0;
 }
 
-static int get_atomisp_dis_statistics32(struct atomisp_dis_statistics *kp,
+static int get_atomisp_dis_statistics32(struct atomisp_dis_statistics __user *kp,
 					struct atomisp_dis_statistics32 __user *up)
 {
 	compat_uptr_t hor_prod_odd_real;
@@ -96,67 +91,99 @@ static int get_atomisp_dis_statistics32(struct atomisp_dis_statistics *kp,
 	compat_uptr_t ver_prod_even_imag;
 
 	if (!access_ok(up, sizeof(struct atomisp_dis_statistics32)) ||
-	    copy_from_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) ||
-	    get_user(hor_prod_odd_real, &up->dvs2_stat.hor_prod.odd_real) ||
-	    get_user(hor_prod_odd_imag, &up->dvs2_stat.hor_prod.odd_imag) ||
-	    get_user(hor_prod_even_real, &up->dvs2_stat.hor_prod.even_real) ||
-	    get_user(hor_prod_even_imag, &up->dvs2_stat.hor_prod.even_imag) ||
-	    get_user(ver_prod_odd_real, &up->dvs2_stat.ver_prod.odd_real) ||
-	    get_user(ver_prod_odd_imag, &up->dvs2_stat.ver_prod.odd_imag) ||
-	    get_user(ver_prod_even_real, &up->dvs2_stat.ver_prod.even_real) ||
-	    get_user(ver_prod_even_imag, &up->dvs2_stat.ver_prod.even_imag) ||
-	    get_user(kp->exp_id, &up->exp_id))
+	    copy_in_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) ||
+	    get_user(hor_prod_odd_real,
+		     &up->dvs2_stat.hor_prod.odd_real) ||
+	    get_user(hor_prod_odd_imag,
+		     &up->dvs2_stat.hor_prod.odd_imag) ||
+	    get_user(hor_prod_even_real,
+		     &up->dvs2_stat.hor_prod.even_real) ||
+	    get_user(hor_prod_even_imag,
+		     &up->dvs2_stat.hor_prod.even_imag) ||
+	    get_user(ver_prod_odd_real,
+		     &up->dvs2_stat.ver_prod.odd_real) ||
+	    get_user(ver_prod_odd_imag,
+		     &up->dvs2_stat.ver_prod.odd_imag) ||
+	    get_user(ver_prod_even_real,
+		     &up->dvs2_stat.ver_prod.even_real) ||
+	    get_user(ver_prod_even_imag,
+		     &up->dvs2_stat.ver_prod.even_imag) ||
+	    assign_in_user(&kp->exp_id, &up->exp_id) ||
+	    put_user(compat_ptr(hor_prod_odd_real),
+		     &kp->dvs2_stat.hor_prod.odd_real) ||
+	    put_user(compat_ptr(hor_prod_odd_imag),
+		     &kp->dvs2_stat.hor_prod.odd_imag) ||
+	    put_user(compat_ptr(hor_prod_even_real),
+		     &kp->dvs2_stat.hor_prod.even_real) ||
+	    put_user(compat_ptr(hor_prod_even_imag),
+		     &kp->dvs2_stat.hor_prod.even_imag) ||
+	    put_user(compat_ptr(ver_prod_odd_real),
+		     &kp->dvs2_stat.ver_prod.odd_real) ||
+	    put_user(compat_ptr(ver_prod_odd_imag),
+		     &kp->dvs2_stat.ver_prod.odd_imag) ||
+	    put_user(compat_ptr(ver_prod_even_real),
+		     &kp->dvs2_stat.ver_prod.even_real) ||
+	    put_user(compat_ptr(ver_prod_even_imag),
+		     &kp->dvs2_stat.ver_prod.even_imag))
 		return -EFAULT;
 
-	kp->dvs2_stat.hor_prod.odd_real = compat_ptr(hor_prod_odd_real);
-	kp->dvs2_stat.hor_prod.odd_imag = compat_ptr(hor_prod_odd_imag);
-	kp->dvs2_stat.hor_prod.even_real = compat_ptr(hor_prod_even_real);
-	kp->dvs2_stat.hor_prod.even_imag = compat_ptr(hor_prod_even_imag);
-	kp->dvs2_stat.ver_prod.odd_real = compat_ptr(ver_prod_odd_real);
-	kp->dvs2_stat.ver_prod.odd_imag = compat_ptr(ver_prod_odd_imag);
-	kp->dvs2_stat.ver_prod.even_real = compat_ptr(ver_prod_even_real);
-	kp->dvs2_stat.ver_prod.even_imag = compat_ptr(ver_prod_even_imag);
 	return 0;
 }
 
-static int put_atomisp_dis_statistics32(struct atomisp_dis_statistics *kp,
+static int put_atomisp_dis_statistics32(struct atomisp_dis_statistics __user *kp,
 					struct atomisp_dis_statistics32 __user *up)
 {
-	compat_uptr_t hor_prod_odd_real =
-	    (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.odd_real);
-	compat_uptr_t hor_prod_odd_imag =
-	    (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.odd_imag);
-	compat_uptr_t hor_prod_even_real =
-	    (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.even_real);
-	compat_uptr_t hor_prod_even_imag =
-	    (compat_uptr_t)((uintptr_t)kp->dvs2_stat.hor_prod.even_imag);
-	compat_uptr_t ver_prod_odd_real =
-	    (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.odd_real);
-	compat_uptr_t ver_prod_odd_imag =
-	    (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.odd_imag);
-	compat_uptr_t ver_prod_even_real =
-	    (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.even_real);
-	compat_uptr_t ver_prod_even_imag =
-	    (compat_uptr_t)((uintptr_t)kp->dvs2_stat.ver_prod.even_imag);
-
-	if (!access_ok(up, sizeof(struct atomisp_dis_statistics32)) ||
-	    copy_to_user(up, kp, sizeof(struct atomisp_dvs_grid_info)) ||
-	    put_user(hor_prod_odd_real, &up->dvs2_stat.hor_prod.odd_real) ||
-	    put_user(hor_prod_odd_imag, &up->dvs2_stat.hor_prod.odd_imag) ||
-	    put_user(hor_prod_even_real, &up->dvs2_stat.hor_prod.even_real) ||
-	    put_user(hor_prod_even_imag, &up->dvs2_stat.hor_prod.even_imag) ||
-	    put_user(ver_prod_odd_real, &up->dvs2_stat.ver_prod.odd_real) ||
-	    put_user(ver_prod_odd_imag, &up->dvs2_stat.ver_prod.odd_imag) ||
-	    put_user(ver_prod_even_real, &up->dvs2_stat.ver_prod.even_real) ||
-	    put_user(ver_prod_even_imag, &up->dvs2_stat.ver_prod.even_imag) ||
-	    put_user(kp->exp_id, &up->exp_id))
+	void __user *hor_prod_odd_real;
+	void __user *hor_prod_odd_imag;
+	void __user *hor_prod_even_real;
+	void __user *hor_prod_even_imag;
+	void __user *ver_prod_odd_real;
+	void __user *ver_prod_odd_imag;
+	void __user *ver_prod_even_real;
+	void __user *ver_prod_even_imag;
+
+	if (!!access_ok(up, sizeof(struct atomisp_dis_statistics32)) ||
+	    copy_in_user(up, kp, sizeof(struct atomisp_dvs_grid_info)) ||
+	    get_user(hor_prod_odd_real,
+		     &kp->dvs2_stat.hor_prod.odd_real) ||
+	    get_user(hor_prod_odd_imag,
+		     &kp->dvs2_stat.hor_prod.odd_imag) ||
+	    get_user(hor_prod_even_real,
+		     &kp->dvs2_stat.hor_prod.even_real) ||
+	    get_user(hor_prod_even_imag,
+		     &kp->dvs2_stat.hor_prod.even_imag) ||
+	    get_user(ver_prod_odd_real,
+		     &kp->dvs2_stat.ver_prod.odd_real) ||
+	    get_user(ver_prod_odd_imag,
+		     &kp->dvs2_stat.ver_prod.odd_imag) ||
+	    get_user(ver_prod_even_real,
+		     &kp->dvs2_stat.ver_prod.even_real) ||
+	    get_user(ver_prod_even_imag,
+		     &kp->dvs2_stat.ver_prod.even_imag) ||
+	    put_user(ptr_to_compat(hor_prod_odd_real),
+		     &up->dvs2_stat.hor_prod.odd_real) ||
+	    put_user(ptr_to_compat(hor_prod_odd_imag),
+		     &up->dvs2_stat.hor_prod.odd_imag) ||
+	    put_user(ptr_to_compat(hor_prod_even_real),
+		     &up->dvs2_stat.hor_prod.even_real) ||
+	    put_user(ptr_to_compat(hor_prod_even_imag),
+		     &up->dvs2_stat.hor_prod.even_imag) ||
+	    put_user(ptr_to_compat(ver_prod_odd_real),
+		     &up->dvs2_stat.ver_prod.odd_real) ||
+	    put_user(ptr_to_compat(ver_prod_odd_imag),
+		     &up->dvs2_stat.ver_prod.odd_imag) ||
+	    put_user(ptr_to_compat(ver_prod_even_real),
+		     &up->dvs2_stat.ver_prod.even_real) ||
+	    put_user(ptr_to_compat(ver_prod_even_imag),
+		     &up->dvs2_stat.ver_prod.even_imag) ||
+	    assign_in_user(&up->exp_id, &kp->exp_id))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_atomisp_dis_coefficients32(struct atomisp_dis_coefficients *kp,
-	struct atomisp_dis_coefficients32 __user *up)
+static int get_atomisp_dis_coefficients32(struct atomisp_dis_coefficients __user *kp,
+					  struct atomisp_dis_coefficients32 __user *up)
 {
 	compat_uptr_t hor_coefs_odd_real;
 	compat_uptr_t hor_coefs_odd_imag;
@@ -168,7 +195,7 @@ static int get_atomisp_dis_coefficients32(struct atomisp_dis_coefficients *kp,
 	compat_uptr_t ver_coefs_even_imag;
 
 	if (!access_ok(up, sizeof(struct atomisp_dis_coefficients32)) ||
-	    copy_from_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) ||
+	    copy_in_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) ||
 	    get_user(hor_coefs_odd_real, &up->hor_coefs.odd_real) ||
 	    get_user(hor_coefs_odd_imag, &up->hor_coefs.odd_imag) ||
 	    get_user(hor_coefs_even_real, &up->hor_coefs.even_real) ||
@@ -176,22 +203,30 @@ static int get_atomisp_dis_coefficients32(struct atomisp_dis_coefficients *kp,
 	    get_user(ver_coefs_odd_real, &up->ver_coefs.odd_real) ||
 	    get_user(ver_coefs_odd_imag, &up->ver_coefs.odd_imag) ||
 	    get_user(ver_coefs_even_real, &up->ver_coefs.even_real) ||
-	    get_user(ver_coefs_even_imag, &up->ver_coefs.even_imag))
+	    get_user(ver_coefs_even_imag, &up->ver_coefs.even_imag) ||
+	    put_user(compat_ptr(hor_coefs_odd_real),
+		     &kp->hor_coefs.odd_real) ||
+	    put_user(compat_ptr(hor_coefs_odd_imag),
+		     &kp->hor_coefs.odd_imag) ||
+	    put_user(compat_ptr(hor_coefs_even_real),
+		     &kp->hor_coefs.even_real) ||
+	    put_user(compat_ptr(hor_coefs_even_imag),
+		     &kp->hor_coefs.even_imag) ||
+	    put_user(compat_ptr(ver_coefs_odd_real),
+		     &kp->ver_coefs.odd_real) ||
+	    put_user(compat_ptr(ver_coefs_odd_imag),
+		     &kp->ver_coefs.odd_imag) ||
+	    put_user(compat_ptr(ver_coefs_even_real),
+		     &kp->ver_coefs.even_real) ||
+	    put_user(compat_ptr(ver_coefs_even_imag),
+		     &kp->ver_coefs.even_imag))
 		return -EFAULT;
 
-	kp->hor_coefs.odd_real = compat_ptr(hor_coefs_odd_real);
-	kp->hor_coefs.odd_imag = compat_ptr(hor_coefs_odd_imag);
-	kp->hor_coefs.even_real = compat_ptr(hor_coefs_even_real);
-	kp->hor_coefs.even_imag = compat_ptr(hor_coefs_even_imag);
-	kp->ver_coefs.odd_real = compat_ptr(ver_coefs_odd_real);
-	kp->ver_coefs.odd_imag = compat_ptr(ver_coefs_odd_imag);
-	kp->ver_coefs.even_real = compat_ptr(ver_coefs_even_real);
-	kp->ver_coefs.even_imag = compat_ptr(ver_coefs_even_imag);
 	return 0;
 }
 
-static int get_atomisp_dvs_6axis_config32(struct atomisp_dvs_6axis_config *kp,
-	struct atomisp_dvs_6axis_config32 __user *up)
+static int get_atomisp_dvs_6axis_config32(struct atomisp_dvs_6axis_config __user *kp,
+					  struct atomisp_dvs_6axis_config32 __user *up)
 {
 	compat_uptr_t xcoords_y;
 	compat_uptr_t ycoords_y;
@@ -199,62 +234,63 @@ static int get_atomisp_dvs_6axis_config32(struct atomisp_dvs_6axis_config *kp,
 	compat_uptr_t ycoords_uv;
 
 	if (!access_ok(up, sizeof(struct atomisp_dvs_6axis_config32)) ||
-	    get_user(kp->exp_id, &up->exp_id) ||
-	    get_user(kp->width_y, &up->width_y) ||
-	    get_user(kp->height_y, &up->height_y) ||
-	    get_user(kp->width_uv, &up->width_uv) ||
-	    get_user(kp->height_uv, &up->height_uv) ||
+	    assign_in_user(&kp->exp_id, &up->exp_id) ||
+	    assign_in_user(&kp->width_y, &up->width_y) ||
+	    assign_in_user(&kp->height_y, &up->height_y) ||
+	    assign_in_user(&kp->width_uv, &up->width_uv) ||
+	    assign_in_user(&kp->height_uv, &up->height_uv) ||
 	    get_user(xcoords_y, &up->xcoords_y) ||
 	    get_user(ycoords_y, &up->ycoords_y) ||
 	    get_user(xcoords_uv, &up->xcoords_uv) ||
-	    get_user(ycoords_uv, &up->ycoords_uv))
+	    get_user(ycoords_uv, &up->ycoords_uv) ||
+	    put_user(compat_ptr(xcoords_y), &kp->xcoords_y) ||
+	    put_user(compat_ptr(ycoords_y), &kp->ycoords_y) ||
+	    put_user(compat_ptr(xcoords_uv), &kp->xcoords_uv) ||
+	    put_user(compat_ptr(ycoords_uv), &kp->ycoords_uv))
 		return -EFAULT;
 
-	kp->xcoords_y = (void __force *)compat_ptr(xcoords_y);
-	kp->ycoords_y = (void __force *)compat_ptr(ycoords_y);
-	kp->xcoords_uv = (void __force *)compat_ptr(xcoords_uv);
-	kp->ycoords_uv = (void __force *)compat_ptr(ycoords_uv);
 	return 0;
 }
 
-static int get_atomisp_3a_statistics32(struct atomisp_3a_statistics *kp,
+static int get_atomisp_3a_statistics32(struct atomisp_3a_statistics __user *kp,
 				       struct atomisp_3a_statistics32 __user *up)
 {
 	compat_uptr_t data;
 	compat_uptr_t rgby_data;
 
 	if (!access_ok(up, sizeof(struct atomisp_3a_statistics32)) ||
-	    copy_from_user(kp, up, sizeof(struct atomisp_grid_info)) ||
+	    copy_in_user(kp, up, sizeof(struct atomisp_grid_info)) ||
 	    get_user(rgby_data, &up->rgby_data) ||
+	    put_user(compat_ptr(rgby_data), &kp->rgby_data) ||
 	    get_user(data, &up->data) ||
-	    get_user(kp->exp_id, &up->exp_id) ||
-	    get_user(kp->isp_config_id, &up->isp_config_id))
+	    put_user(compat_ptr(data), &kp->data) ||
+	    assign_in_user(&kp->exp_id, &up->exp_id) ||
+	    assign_in_user(&kp->isp_config_id, &up->isp_config_id))
 		return -EFAULT;
 
-	kp->data = compat_ptr(data);
-	kp->rgby_data = compat_ptr(rgby_data);
-
 	return 0;
 }
 
-static int put_atomisp_3a_statistics32(struct atomisp_3a_statistics *kp,
+static int put_atomisp_3a_statistics32(struct atomisp_3a_statistics __user *kp,
 				       struct atomisp_3a_statistics32 __user *up)
 {
-	compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
-	compat_uptr_t rgby_data = (compat_uptr_t)((uintptr_t)kp->rgby_data);
+	void __user *data;
+	void __user *rgby_data;
 
 	if (!access_ok(up, sizeof(struct atomisp_3a_statistics32)) ||
 	    copy_to_user(up, kp, sizeof(struct atomisp_grid_info)) ||
-	    put_user(rgby_data, &up->rgby_data) ||
-	    put_user(data, &up->data) ||
-	    put_user(kp->exp_id, &up->exp_id) ||
-	    put_user(kp->isp_config_id, &up->isp_config_id))
+	    get_user(rgby_data, &kp->rgby_data) ||
+	    put_user(ptr_to_compat(rgby_data), &up->rgby_data) ||
+	    get_user(data, &kp->data) ||
+	    put_user(ptr_to_compat(data), &up->data) ||
+	    assign_in_user(&up->exp_id, &kp->exp_id) ||
+	    assign_in_user(&up->isp_config_id, &kp->isp_config_id))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_atomisp_metadata_stat32(struct atomisp_metadata *kp,
+static int get_atomisp_metadata_stat32(struct atomisp_metadata __user *kp,
 				       struct atomisp_metadata32 __user *up)
 {
 	compat_uptr_t data;
@@ -262,555 +298,524 @@ static int get_atomisp_metadata_stat32(struct atomisp_metadata *kp,
 
 	if (!access_ok(up, sizeof(struct atomisp_metadata32)) ||
 	    get_user(data, &up->data) ||
-	    get_user(kp->width, &up->width) ||
-	    get_user(kp->height, &up->height) ||
-	    get_user(kp->stride, &up->stride) ||
-	    get_user(kp->exp_id, &up->exp_id) ||
-	    get_user(effective_width, &up->effective_width))
+	    put_user(compat_ptr(data), &kp->data) ||
+	    assign_in_user(&kp->width, &up->width) ||
+	    assign_in_user(&kp->height, &up->height) ||
+	    assign_in_user(&kp->stride, &up->stride) ||
+	    assign_in_user(&kp->exp_id, &up->exp_id) ||
+	    get_user(effective_width, &up->effective_width) ||
+	    put_user(compat_ptr(effective_width), &kp->effective_width))
 		return -EFAULT;
 
-	kp->data = compat_ptr(data);
-	kp->effective_width = (void __force *)compat_ptr(effective_width);
 	return 0;
 }
 
-static int put_atomisp_metadata_stat32(struct atomisp_metadata *kp,
-				       struct atomisp_metadata32 __user *up)
+static int put_atomisp_metadata_stat32(struct atomisp_metadata __user *kp,
+				struct atomisp_metadata32 __user *up)
 {
-	compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
-	compat_uptr_t effective_width =
-	    (compat_uptr_t)((uintptr_t)kp->effective_width);
+	void __user *data;
+	void __user *effective_width;
+
 	if (!access_ok(up, sizeof(struct atomisp_metadata32)) ||
-	    put_user(data, &up->data) ||
-	    put_user(kp->width, &up->width) ||
-	    put_user(kp->height, &up->height) ||
-	    put_user(kp->stride, &up->stride) ||
-	    put_user(kp->exp_id, &up->exp_id) ||
-	    put_user(effective_width, &up->effective_width))
+	    get_user(data, &kp->data) ||
+	    put_user(ptr_to_compat(data), &up->data) ||
+	    assign_in_user(&up->width, &kp->width) ||
+	    assign_in_user(&up->height, &kp->height) ||
+	    assign_in_user(&up->stride, &kp->stride) ||
+	    assign_in_user(&up->exp_id, &kp->exp_id) ||
+	    get_user(effective_width, &kp->effective_width) ||
+	    put_user(ptr_to_compat(effective_width), &up->effective_width))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int put_atomisp_metadata_by_type_stat32(
-    struct atomisp_metadata_with_type *kp,
-    struct atomisp_metadata_with_type32 __user *up)
+static int
+put_atomisp_metadata_by_type_stat32(struct atomisp_metadata_with_type __user *kp,
+				    struct atomisp_metadata_with_type32 __user *up)
 {
-	compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
-	compat_uptr_t effective_width =
-	    (compat_uptr_t)((uintptr_t)kp->effective_width);
+	void __user *data;
+	void __user *effective_width;
+
 	if (!access_ok(up, sizeof(struct atomisp_metadata_with_type32)) ||
-	    put_user(data, &up->data) ||
-	    put_user(kp->width, &up->width) ||
-	    put_user(kp->height, &up->height) ||
-	    put_user(kp->stride, &up->stride) ||
-	    put_user(kp->exp_id, &up->exp_id) ||
-	    put_user(effective_width, &up->effective_width) ||
-	    put_user(kp->type, &up->type))
+	    get_user(data, &kp->data) ||
+	    put_user(ptr_to_compat(data), &up->data) ||
+	    assign_in_user(&up->width, &kp->width) ||
+	    assign_in_user(&up->height, &kp->height) ||
+	    assign_in_user(&up->stride, &kp->stride) ||
+	    assign_in_user(&up->exp_id, &kp->exp_id) ||
+	    get_user(effective_width, &kp->effective_width) ||
+	    put_user(ptr_to_compat(effective_width),
+		     &up->effective_width) ||
+	    assign_in_user(&up->type, &kp->type))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_atomisp_metadata_by_type_stat32(
-    struct atomisp_metadata_with_type *kp,
-    struct atomisp_metadata_with_type32 __user *up)
+static int
+get_atomisp_metadata_by_type_stat32(struct atomisp_metadata_with_type __user *kp,
+				    struct atomisp_metadata_with_type32 __user *up)
 {
 	compat_uptr_t data;
 	compat_uptr_t effective_width;
 
 	if (!access_ok(up, sizeof(struct atomisp_metadata_with_type32)) ||
 	    get_user(data, &up->data) ||
-	    get_user(kp->width, &up->width) ||
-	    get_user(kp->height, &up->height) ||
-	    get_user(kp->stride, &up->stride) ||
-	    get_user(kp->exp_id, &up->exp_id) ||
+	    put_user(compat_ptr(data), &kp->data) ||
+	    assign_in_user(&kp->width, &up->width) ||
+	    assign_in_user(&kp->height, &up->height) ||
+	    assign_in_user(&kp->stride, &up->stride) ||
+	    assign_in_user(&kp->exp_id, &up->exp_id) ||
 	    get_user(effective_width, &up->effective_width) ||
-	    get_user(kp->type, &up->type))
+	    put_user(compat_ptr(effective_width), &kp->effective_width) ||
+	    assign_in_user(&kp->type, &up->type))
 		return -EFAULT;
 
-	kp->data = compat_ptr(data);
-	kp->effective_width = (void __force *)compat_ptr(effective_width);
 	return 0;
 }
 
-static int get_atomisp_morph_table32(struct atomisp_morph_table *kp,
-				     struct atomisp_morph_table32 __user *up)
+static int
+get_atomisp_morph_table32(struct atomisp_morph_table __user *kp,
+			  struct atomisp_morph_table32 __user *up)
 {
 	unsigned int n = ATOMISP_MORPH_TABLE_NUM_PLANES;
 
 	if (!access_ok(up, sizeof(struct atomisp_morph_table32)) ||
-	    get_user(kp->enabled, &up->enabled) ||
-	    get_user(kp->width, &up->width) ||
-	    get_user(kp->height, &up->height))
-		return -EFAULT;
+		assign_in_user(&kp->enabled, &up->enabled) ||
+		assign_in_user(&kp->width, &up->width) ||
+		assign_in_user(&kp->height, &up->height))
+			return -EFAULT;
 
 	while (n-- > 0) {
-		uintptr_t *coord_kp = (uintptr_t *)&kp->coordinates_x[n];
-
-		if (get_user((*coord_kp), &up->coordinates_x[n]))
-			return -EFAULT;
+		compat_uptr_t coord_kp;
 
-		coord_kp = (uintptr_t *)&kp->coordinates_y[n];
-		if (get_user((*coord_kp), &up->coordinates_y[n]))
+		if (get_user(coord_kp, &up->coordinates_x[n]) ||
+		    put_user(compat_ptr(coord_kp), &kp->coordinates_x[n]) ||
+		    get_user(coord_kp, &up->coordinates_y[n]) ||
+		    put_user(compat_ptr(coord_kp), &kp->coordinates_y[n]))
 			return -EFAULT;
 	}
 	return 0;
 }
 
-static int put_atomisp_morph_table32(struct atomisp_morph_table *kp,
+static int put_atomisp_morph_table32(struct atomisp_morph_table __user *kp,
 				     struct atomisp_morph_table32 __user *up)
 {
 	unsigned int n = ATOMISP_MORPH_TABLE_NUM_PLANES;
 
 	if (!access_ok(up, sizeof(struct atomisp_morph_table32)) ||
-	    put_user(kp->enabled, &up->enabled) ||
-	    put_user(kp->width, &up->width) ||
-	    put_user(kp->height, &up->height))
-		return -EFAULT;
+		assign_in_user(&up->enabled, &kp->enabled) ||
+		assign_in_user(&up->width, &kp->width) ||
+		assign_in_user(&up->height, &kp->height))
+			return -EFAULT;
 
 	while (n-- > 0) {
-		uintptr_t *coord_kp = (uintptr_t *)&kp->coordinates_x[n];
+		void __user *coord_kp;
 
-		if (put_user((*coord_kp), &up->coordinates_x[n]))
-			return -EFAULT;
-
-		coord_kp = (uintptr_t *)&kp->coordinates_y[n];
-		if (put_user((*coord_kp), &up->coordinates_y[n]))
+		if (get_user(coord_kp, &kp->coordinates_x[n]) ||
+		    put_user(ptr_to_compat(coord_kp), &up->coordinates_x[n]) ||
+		    get_user(coord_kp, &kp->coordinates_y[n]) ||
+		    put_user(ptr_to_compat(coord_kp), &up->coordinates_y[n]))
 			return -EFAULT;
 	}
 	return 0;
 }
 
-static int get_atomisp_overlay32(struct atomisp_overlay *kp,
+static int get_atomisp_overlay32(struct atomisp_overlay __user *kp,
 				 struct atomisp_overlay32 __user *up)
 {
 	compat_uptr_t frame;
 
 	if (!access_ok(up, sizeof(struct atomisp_overlay32)) ||
 	    get_user(frame, &up->frame) ||
-	    get_user(kp->bg_y, &up->bg_y) ||
-	    get_user(kp->bg_u, &up->bg_u) ||
-	    get_user(kp->bg_v, &up->bg_v) ||
-	    get_user(kp->blend_input_perc_y, &up->blend_input_perc_y) ||
-	    get_user(kp->blend_input_perc_u, &up->blend_input_perc_u) ||
-	    get_user(kp->blend_input_perc_v, &up->blend_input_perc_v) ||
-	    get_user(kp->blend_overlay_perc_y, &up->blend_overlay_perc_y) ||
-	    get_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
-	    get_user(kp->blend_overlay_perc_v, &up->blend_overlay_perc_v) ||
-	    get_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
-	    get_user(kp->overlay_start_x, &up->overlay_start_x) ||
-	    get_user(kp->overlay_start_y, &up->overlay_start_y))
+	    put_user(compat_ptr(frame), &kp->frame) ||
+	    assign_in_user(&kp->bg_y, &up->bg_y) ||
+	    assign_in_user(&kp->bg_u, &up->bg_u) ||
+	    assign_in_user(&kp->bg_v, &up->bg_v) ||
+	    assign_in_user(&kp->blend_input_perc_y,
+			   &up->blend_input_perc_y) ||
+	    assign_in_user(&kp->blend_input_perc_u,
+			   &up->blend_input_perc_u) ||
+	    assign_in_user(&kp->blend_input_perc_v,
+			   &up->blend_input_perc_v) ||
+	    assign_in_user(&kp->blend_overlay_perc_y,
+			   &up->blend_overlay_perc_y) ||
+	    assign_in_user(&kp->blend_overlay_perc_u,
+			   &up->blend_overlay_perc_u) ||
+	    assign_in_user(&kp->blend_overlay_perc_v,
+			   &up->blend_overlay_perc_v) ||
+	    assign_in_user(&kp->overlay_start_x, &up->overlay_start_x) ||
+	    assign_in_user(&kp->overlay_start_y, &up->overlay_start_y))
 		return -EFAULT;
 
-	kp->frame = (void __force *)compat_ptr(frame);
 	return 0;
 }
 
-static int put_atomisp_overlay32(struct atomisp_overlay *kp,
+static int put_atomisp_overlay32(struct atomisp_overlay __user *kp,
 				 struct atomisp_overlay32 __user *up)
 {
-	compat_uptr_t frame = (compat_uptr_t)((uintptr_t)kp->frame);
+	void __user *frame;
 
 	if (!access_ok(up, sizeof(struct atomisp_overlay32)) ||
-	    put_user(frame, &up->frame) ||
-	    put_user(kp->bg_y, &up->bg_y) ||
-	    put_user(kp->bg_u, &up->bg_u) ||
-	    put_user(kp->bg_v, &up->bg_v) ||
-	    put_user(kp->blend_input_perc_y, &up->blend_input_perc_y) ||
-	    put_user(kp->blend_input_perc_u, &up->blend_input_perc_u) ||
-	    put_user(kp->blend_input_perc_v, &up->blend_input_perc_v) ||
-	    put_user(kp->blend_overlay_perc_y, &up->blend_overlay_perc_y) ||
-	    put_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
-	    put_user(kp->blend_overlay_perc_v, &up->blend_overlay_perc_v) ||
-	    put_user(kp->blend_overlay_perc_u, &up->blend_overlay_perc_u) ||
-	    put_user(kp->overlay_start_x, &up->overlay_start_x)
-	    put_user(kp->overlay_start_y, &up->overlay_start_y))
+	    get_user(frame, &kp->frame) ||
+	    put_user(ptr_to_compat(frame), &up->frame) ||
+	    assign_in_user(&up->bg_y, &kp->bg_y) ||
+	    assign_in_user(&up->bg_u, &kp->bg_u) ||
+	    assign_in_user(&up->bg_v, &kp->bg_v) ||
+	    assign_in_user(&up->blend_input_perc_y,
+			   &kp->blend_input_perc_y) ||
+	    assign_in_user(&up->blend_input_perc_u,
+			   &kp->blend_input_perc_u) ||
+	    assign_in_user(&up->blend_input_perc_v,
+			   &kp->blend_input_perc_v) ||
+	    assign_in_user(&up->blend_overlay_perc_y,
+			   &kp->blend_overlay_perc_y) ||
+	    assign_in_user(&up->blend_overlay_perc_u,
+			   &kp->blend_overlay_perc_u) ||
+	    assign_in_user(&up->blend_overlay_perc_v,
+			   &kp->blend_overlay_perc_v) ||
+	    assign_in_user(&up->overlay_start_x, &kp->overlay_start_x) ||
+	    assign_in_user(&up->overlay_start_y, &kp->overlay_start_y))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_atomisp_calibration_group32(
-    struct atomisp_calibration_group *kp,
-    struct atomisp_calibration_group32 __user *up)
+static int
+get_atomisp_calibration_group32(struct atomisp_calibration_group __user *kp,
+				struct atomisp_calibration_group32 __user *up)
 {
 	compat_uptr_t calb_grp_values;
 
 	if (!access_ok(up, sizeof(struct atomisp_calibration_group32)) ||
-	    get_user(kp->size, &up->size) ||
-	    get_user(kp->type, &up->type) ||
-	    get_user(calb_grp_values, &up->calb_grp_values))
+	    assign_in_user(&kp->size, &up->size) ||
+	    assign_in_user(&kp->type, &up->type) ||
+	    get_user(calb_grp_values, &up->calb_grp_values) ||
+	    put_user(compat_ptr(calb_grp_values), &kp->calb_grp_values))
 		return -EFAULT;
 
-	kp->calb_grp_values = (void __force *)compat_ptr(calb_grp_values);
 	return 0;
 }
 
-static int put_atomisp_calibration_group32(
-    struct atomisp_calibration_group *kp,
-    struct atomisp_calibration_group32 __user *up)
+static int
+put_atomisp_calibration_group32(struct atomisp_calibration_group __user *kp,
+				struct atomisp_calibration_group32 __user *up)
 {
-	compat_uptr_t calb_grp_values =
-	    (compat_uptr_t)((uintptr_t)kp->calb_grp_values);
+	void __user *calb_grp_values;
 
 	if (!access_ok(up, sizeof(struct atomisp_calibration_group32)) ||
-	    put_user(kp->size, &up->size) ||
-	    put_user(kp->type, &up->type) ||
-	    put_user(calb_grp_values, &up->calb_grp_values))
+	    assign_in_user(&up->size, &kp->size) ||
+	    assign_in_user(&up->type, &kp->type) ||
+	    get_user(calb_grp_values, &kp->calb_grp_values) ||
+	    put_user(ptr_to_compat(calb_grp_values), &up->calb_grp_values))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_atomisp_acc_fw_load32(struct atomisp_acc_fw_load *kp,
+static int get_atomisp_acc_fw_load32(struct atomisp_acc_fw_load __user *kp,
 				     struct atomisp_acc_fw_load32 __user *up)
 {
 	compat_uptr_t data;
 
 	if (!access_ok(up, sizeof(struct atomisp_acc_fw_load32)) ||
-	    get_user(kp->size, &up->size) ||
-	    get_user(kp->fw_handle, &up->fw_handle) ||
-	    get_user(data, &up->data))
+	    assign_in_user(&kp->size, &up->size) ||
+	    assign_in_user(&kp->fw_handle, &up->fw_handle) ||
+	    get_user(data, &up->data) ||
+	    put_user(compat_ptr(data), &kp->data))
 		return -EFAULT;
 
-	kp->data = compat_ptr(data);
 	return 0;
 }
 
-static int put_atomisp_acc_fw_load32(struct atomisp_acc_fw_load *kp,
+static int put_atomisp_acc_fw_load32(struct atomisp_acc_fw_load __user *kp,
 				     struct atomisp_acc_fw_load32 __user *up)
 {
-	compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
+	void __user *data;
 
 	if (!access_ok(up, sizeof(struct atomisp_acc_fw_load32)) ||
-	    put_user(kp->size, &up->size) ||
-	    put_user(kp->fw_handle, &up->fw_handle) ||
-	    put_user(data, &up->data))
+	    assign_in_user(&up->size, &kp->size) ||
+	    assign_in_user(&up->fw_handle, &kp->fw_handle) ||
+	    get_user(data, &kp->data) ||
+	    put_user(ptr_to_compat(data), &up->data))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg *kp,
+static int get_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg __user *kp,
 				    struct atomisp_acc_fw_arg32 __user *up)
 {
 	compat_uptr_t value;
 
 	if (!access_ok(up, sizeof(struct atomisp_acc_fw_arg32)) ||
-	    get_user(kp->fw_handle, &up->fw_handle) ||
-	    get_user(kp->index, &up->index) ||
+	    assign_in_user(&kp->fw_handle, &up->fw_handle) ||
+	    assign_in_user(&kp->index, &up->index) ||
 	    get_user(value, &up->value) ||
-	    get_user(kp->size, &up->size))
+	    put_user(compat_ptr(value), &kp->value) ||
+	    assign_in_user(&kp->size, &up->size))
 		return -EFAULT;
 
-	kp->value = compat_ptr(value);
 	return 0;
 }
 
-static int put_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg *kp,
+static int put_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg __user *kp,
 				    struct atomisp_acc_fw_arg32 __user *up)
 {
-	compat_uptr_t value = (compat_uptr_t)((uintptr_t)kp->value);
+	void __user *value;
 
 	if (!access_ok(up, sizeof(struct atomisp_acc_fw_arg32)) ||
-	    put_user(kp->fw_handle, &up->fw_handle) ||
-	    put_user(kp->index, &up->index) ||
-	    put_user(value, &up->value) ||
-	    put_user(kp->size, &up->size))
+	    assign_in_user(&up->fw_handle, &kp->fw_handle) ||
+	    assign_in_user(&up->index, &kp->index) ||
+	    get_user(value, &kp->value) ||
+	    put_user(ptr_to_compat(value), &up->value) ||
+	    assign_in_user(&up->size, &kp->size))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_v4l2_private_int_data32(struct v4l2_private_int_data *kp,
+static int get_v4l2_private_int_data32(struct v4l2_private_int_data __user *kp,
 				       struct v4l2_private_int_data32 __user *up)
 {
 	compat_uptr_t data;
 
 	if (!access_ok(up, sizeof(struct v4l2_private_int_data32)) ||
-	    get_user(kp->size, &up->size) ||
+	    assign_in_user(&kp->size, &up->size) ||
 	    get_user(data, &up->data) ||
-	    get_user(kp->reserved[0], &up->reserved[0]) ||
-	    get_user(kp->reserved[1], &up->reserved[1]))
+	    put_user(compat_ptr(data), &kp->data) ||
+	    assign_in_user(&kp->reserved[0], &up->reserved[0]) ||
+	    assign_in_user(&kp->reserved[1], &up->reserved[1]))
 		return -EFAULT;
 
-	kp->data = compat_ptr(data);
 	return 0;
 }
 
-static int put_v4l2_private_int_data32(struct v4l2_private_int_data *kp,
+static int put_v4l2_private_int_data32(struct v4l2_private_int_data __user *kp,
 				       struct v4l2_private_int_data32 __user *up)
 {
-	compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
+	void __user *data;
 
 	if (!access_ok(up, sizeof(struct v4l2_private_int_data32)) ||
-	    put_user(kp->size, &up->size) ||
-	    put_user(data, &up->data) ||
-	    put_user(kp->reserved[0], &up->reserved[0]) ||
-	    put_user(kp->reserved[1], &up->reserved[1]))
+	    assign_in_user(&up->size, &kp->size) ||
+	    get_user(data, &kp->data) ||
+	    put_user(ptr_to_compat(data), &up->data) ||
+	    assign_in_user(&up->reserved[0], &kp->reserved[0]) ||
+	    assign_in_user(&up->reserved[1], &kp->reserved[1]))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_atomisp_shading_table32(struct atomisp_shading_table *kp,
+static int get_atomisp_shading_table32(struct atomisp_shading_table __user *kp,
 				       struct atomisp_shading_table32 __user *up)
 {
 	unsigned int n = ATOMISP_NUM_SC_COLORS;
 
 	if (!access_ok(up, sizeof(struct atomisp_shading_table32)) ||
-	    get_user(kp->enable, &up->enable) ||
-	    get_user(kp->sensor_width, &up->sensor_width) ||
-	    get_user(kp->sensor_height, &up->sensor_height) ||
-	    get_user(kp->width, &up->width) ||
-	    get_user(kp->height, &up->height) ||
-	    get_user(kp->fraction_bits, &up->fraction_bits))
+	    assign_in_user(&kp->enable, &up->enable) ||
+	    assign_in_user(&kp->sensor_width, &up->sensor_width) ||
+	    assign_in_user(&kp->sensor_height, &up->sensor_height) ||
+	    assign_in_user(&kp->width, &up->width) ||
+	    assign_in_user(&kp->height, &up->height) ||
+	    assign_in_user(&kp->fraction_bits, &up->fraction_bits))
 		return -EFAULT;
 
 	while (n-- > 0) {
-		uintptr_t *data_p = (uintptr_t *)&kp->data[n];
+		compat_uptr_t tmp;
 
-		if (get_user((*data_p), &up->data[n]))
+		if (get_user(tmp, &up->data[n]) ||
+		    put_user(compat_ptr(tmp), &kp->data[n]))
 			return -EFAULT;
 	}
 	return 0;
 }
 
-static int get_atomisp_acc_map32(struct atomisp_acc_map *kp,
+static int get_atomisp_acc_map32(struct atomisp_acc_map __user *kp,
 				 struct atomisp_acc_map32 __user *up)
 {
 	compat_uptr_t user_ptr;
 
 	if (!access_ok(up, sizeof(struct atomisp_acc_map32)) ||
-	    get_user(kp->flags, &up->flags) ||
-	    get_user(kp->length, &up->length) ||
+	    assign_in_user(&kp->flags, &up->flags) ||
+	    assign_in_user(&kp->length, &up->length) ||
 	    get_user(user_ptr, &up->user_ptr) ||
-	    get_user(kp->css_ptr, &up->css_ptr) ||
-	    get_user(kp->reserved[0], &up->reserved[0]) ||
-	    get_user(kp->reserved[1], &up->reserved[1]) ||
-	    get_user(kp->reserved[2], &up->reserved[2]) ||
-	    get_user(kp->reserved[3], &up->reserved[3]))
+	    put_user(compat_ptr(user_ptr), &kp->user_ptr) ||
+	    assign_in_user(&kp->css_ptr, &up->css_ptr) ||
+	    assign_in_user(&kp->reserved[0], &up->reserved[0]) ||
+	    assign_in_user(&kp->reserved[1], &up->reserved[1]) ||
+	    assign_in_user(&kp->reserved[2], &up->reserved[2]) ||
+	    assign_in_user(&kp->reserved[3], &up->reserved[3]))
 		return -EFAULT;
 
-	kp->user_ptr = compat_ptr(user_ptr);
 	return 0;
 }
 
-static int put_atomisp_acc_map32(struct atomisp_acc_map *kp,
+static int put_atomisp_acc_map32(struct atomisp_acc_map __user *kp,
 				 struct atomisp_acc_map32 __user *up)
 {
-	compat_uptr_t user_ptr = (compat_uptr_t)((uintptr_t)kp->user_ptr);
+	void __user *user_ptr;
 
 	if (!access_ok(up, sizeof(struct atomisp_acc_map32)) ||
-	    put_user(kp->flags, &up->flags) ||
-	    put_user(kp->length, &up->length) ||
-	    put_user(user_ptr, &up->user_ptr) ||
-	    put_user(kp->css_ptr, &up->css_ptr) ||
-	    put_user(kp->reserved[0], &up->reserved[0]) ||
-	    put_user(kp->reserved[1], &up->reserved[1]) ||
-	    put_user(kp->reserved[2], &up->reserved[2]) ||
-	    put_user(kp->reserved[3], &up->reserved[3]))
+	    assign_in_user(&up->flags, &kp->flags) ||
+	    assign_in_user(&up->length, &kp->length) ||
+	    get_user(user_ptr, &kp->user_ptr) ||
+	    put_user(ptr_to_compat(user_ptr), &up->user_ptr) ||
+	    assign_in_user(&up->css_ptr, &kp->css_ptr) ||
+	    assign_in_user(&up->reserved[0], &kp->reserved[0]) ||
+	    assign_in_user(&up->reserved[1], &kp->reserved[1]) ||
+	    assign_in_user(&up->reserved[2], &kp->reserved[2]) ||
+	    assign_in_user(&up->reserved[3], &kp->reserved[3]))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg *kp,
-	struct atomisp_acc_s_mapped_arg32 __user *up)
+static int
+get_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg __user *kp,
+			       struct atomisp_acc_s_mapped_arg32 __user *up)
 {
 	if (!access_ok(up, sizeof(struct atomisp_acc_s_mapped_arg32)) ||
-	    get_user(kp->fw_handle, &up->fw_handle) ||
-	    get_user(kp->memory, &up->memory) ||
-	    get_user(kp->length, &up->length) ||
-	    get_user(kp->css_ptr, &up->css_ptr))
+	    assign_in_user(&kp->fw_handle, &up->fw_handle) ||
+	    assign_in_user(&kp->memory, &up->memory) ||
+	    assign_in_user(&kp->length, &up->length) ||
+	    assign_in_user(&kp->css_ptr, &up->css_ptr))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int put_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg *kp,
-	struct atomisp_acc_s_mapped_arg32 __user *up)
+static int
+put_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg __user *kp,
+			       struct atomisp_acc_s_mapped_arg32 __user *up)
 {
 	if (!access_ok(up, sizeof(struct atomisp_acc_s_mapped_arg32)) ||
-	    put_user(kp->fw_handle, &up->fw_handle) ||
-	    put_user(kp->memory, &up->memory) ||
-	    put_user(kp->length, &up->length) ||
-	    put_user(kp->css_ptr, &up->css_ptr))
+	    assign_in_user(&up->fw_handle, &kp->fw_handle) ||
+	    assign_in_user(&up->memory, &kp->memory) ||
+	    assign_in_user(&up->length, &kp->length) ||
+	    assign_in_user(&up->css_ptr, &kp->css_ptr))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_atomisp_parameters32(struct atomisp_parameters *kp,
+static int get_atomisp_parameters32(struct atomisp_parameters __user *kp,
 				    struct atomisp_parameters32 __user *up)
 {
 	int n = offsetof(struct atomisp_parameters32, output_frame) /
 		sizeof(compat_uptr_t);
-	unsigned int size, offset = 0;
-	void  __user *user_ptr;
-	unsigned int stp, mtp, dcp, dscp = 0;
+	compat_uptr_t stp, mtp, dcp, dscp;
+	struct {
+		struct atomisp_shading_table shading_table;
+		struct atomisp_morph_table morph_table;
+		struct atomisp_dis_coefficients dvs2_coefs;
+		struct atomisp_dvs_6axis_config dvs_6axis_config;
+	} __user *karg = (void *)(kp + 1);
 
 	if (!access_ok(up, sizeof(struct atomisp_parameters32)))
 		return -EFAULT;
 
 	while (n >= 0) {
-		compat_uptr_t __user *src = ((compat_uptr_t __user *)up) + n;
-		uintptr_t *dst = ((uintptr_t *)kp) + n;
+		compat_uptr_t *src = (compat_uptr_t *)up + n;
+		void * __user *dst = (void * __user *)kp + n;
+		compat_uptr_t tmp;
 
-		if (get_user((*dst), src))
+		if (get_user(tmp, src) || put_user(compat_ptr(tmp), dst))
 			return -EFAULT;
 		n--;
 	}
-	if (get_user(kp->isp_config_id, &up->isp_config_id) ||
-	    get_user(kp->per_frame_setting, &up->per_frame_setting) ||
+
+	if (assign_in_user(&kp->isp_config_id, &up->isp_config_id) ||
+	    assign_in_user(&kp->per_frame_setting, &up->per_frame_setting) ||
 	    get_user(stp, &up->shading_table) ||
 	    get_user(mtp, &up->morph_table) ||
 	    get_user(dcp, &up->dvs2_coefs) ||
 	    get_user(dscp, &up->dvs_6axis_config))
 		return -EFAULT;
 
-	{
-		union {
-			struct atomisp_shading_table shading_table;
-			struct atomisp_morph_table   morph_table;
-			struct atomisp_dis_coefficients dvs2_coefs;
-			struct atomisp_dvs_6axis_config dvs_6axis_config;
-		} karg;
-
-		size = sizeof(struct atomisp_shading_table) +
-		       sizeof(struct atomisp_morph_table) +
-		       sizeof(struct atomisp_dis_coefficients) +
-		       sizeof(struct atomisp_dvs_6axis_config);
-		user_ptr = compat_alloc_user_space(size);
-
-		/* handle shading table */
-		if (stp != 0) {
-			if (get_atomisp_shading_table32(&karg.shading_table,
-							(struct atomisp_shading_table32 __user *)
-							(uintptr_t)stp))
-				return -EFAULT;
-
-			kp->shading_table = (void __force *)user_ptr + offset;
-			offset = sizeof(struct atomisp_shading_table);
-			if (!kp->shading_table)
-				return -EFAULT;
-
-			if (copy_to_user((void __user *)kp->shading_table,
-					 &karg.shading_table,
-					 sizeof(struct atomisp_shading_table)))
-				return -EFAULT;
-		}
-
-		/* handle morph table */
-		if (mtp != 0) {
-			if (get_atomisp_morph_table32(&karg.morph_table,
-						      (struct atomisp_morph_table32 __user *)
-						      (uintptr_t)mtp))
-				return -EFAULT;
-
-			kp->morph_table = (void __force *)user_ptr + offset;
-			offset += sizeof(struct atomisp_morph_table);
-			if (!kp->morph_table)
-				return -EFAULT;
-
-			if (copy_to_user((void __user *)kp->morph_table,
-					 &karg.morph_table,
-					 sizeof(struct atomisp_morph_table)))
-				return -EFAULT;
-		}
-
-		/* handle dvs2 coefficients */
-		if (dcp != 0) {
-			if (get_atomisp_dis_coefficients32(&karg.dvs2_coefs,
-							   (struct atomisp_dis_coefficients32 __user *)
-							   (uintptr_t)dcp))
-				return -EFAULT;
-
-			kp->dvs2_coefs = (void __force *)user_ptr + offset;
-			offset += sizeof(struct atomisp_dis_coefficients);
-			if (!kp->dvs2_coefs)
-				return -EFAULT;
-
-			if (copy_to_user((void __user *)kp->dvs2_coefs,
-					 &karg.dvs2_coefs,
-					 sizeof(struct atomisp_dis_coefficients)))
-				return -EFAULT;
-		}
-		/* handle dvs 6axis configuration */
-		if (dscp != 0) {
-			if (get_atomisp_dvs_6axis_config32(&karg.dvs_6axis_config,
-							   (struct atomisp_dvs_6axis_config32 __user *)
-							   (uintptr_t)dscp))
-				return -EFAULT;
-
-			kp->dvs_6axis_config = (void __force *)user_ptr + offset;
-			offset += sizeof(struct atomisp_dvs_6axis_config);
-			if (!kp->dvs_6axis_config)
-				return -EFAULT;
-
-			if (copy_to_user((void __user *)kp->dvs_6axis_config,
-					 &karg.dvs_6axis_config,
-					 sizeof(struct atomisp_dvs_6axis_config)))
-				return -EFAULT;
-		}
-	}
+	/* handle shading table */
+	if (stp && (get_atomisp_shading_table32(&karg->shading_table,
+						compat_ptr(stp)) ||
+		    put_user(&karg->shading_table, &kp->shading_table)))
+		return -EFAULT;
+
+	/* handle morph table */
+	if (mtp && (get_atomisp_morph_table32(&karg->morph_table,
+					      compat_ptr(mtp)) ||
+		    put_user(&karg->morph_table, &kp->morph_table)))
+		return -EFAULT;
+
+	/* handle dvs2 coefficients */
+	if (dcp && (get_atomisp_dis_coefficients32(&karg->dvs2_coefs,
+						   compat_ptr(dcp)) ||
+		    put_user(&karg->dvs2_coefs, &kp->dvs2_coefs)))
+		return -EFAULT;
+
+	/* handle dvs 6axis configuration */
+	if (dscp &&
+	    (get_atomisp_dvs_6axis_config32(&karg->dvs_6axis_config,
+					    compat_ptr(dscp)) ||
+	     put_user(&karg->dvs_6axis_config, &kp->dvs_6axis_config)))
+		return -EFAULT;
+
 	return 0;
 }
 
-static int get_atomisp_acc_fw_load_to_pipe32(
-    struct atomisp_acc_fw_load_to_pipe *kp,
-    struct atomisp_acc_fw_load_to_pipe32 __user *up)
+static int
+get_atomisp_acc_fw_load_to_pipe32(struct atomisp_acc_fw_load_to_pipe __user *kp,
+				  struct atomisp_acc_fw_load_to_pipe32 __user *up)
 {
 	compat_uptr_t data;
 
 	if (!access_ok(up, sizeof(struct atomisp_acc_fw_load_to_pipe32)) ||
-	    get_user(kp->flags, &up->flags) ||
-	    get_user(kp->fw_handle, &up->fw_handle) ||
-	    get_user(kp->size, &up->size) ||
-	    get_user(kp->type, &up->type) ||
-	    get_user(kp->reserved[0], &up->reserved[0]) ||
-	    get_user(kp->reserved[1], &up->reserved[1]) ||
-	    get_user(kp->reserved[2], &up->reserved[2]) ||
-	    get_user(data, &up->data))
+	    assign_in_user(&kp->flags, &up->flags) ||
+	    assign_in_user(&kp->fw_handle, &up->fw_handle) ||
+	    assign_in_user(&kp->size, &up->size) ||
+	    assign_in_user(&kp->type, &up->type) ||
+	    assign_in_user(&kp->reserved[0], &up->reserved[0]) ||
+	    assign_in_user(&kp->reserved[1], &up->reserved[1]) ||
+	    assign_in_user(&kp->reserved[2], &up->reserved[2]) ||
+	    get_user(data, &up->data) ||
+	    put_user(compat_ptr(data), &kp->data))
 		return -EFAULT;
 
-	kp->data = compat_ptr(data);
 	return 0;
 }
 
-static int put_atomisp_acc_fw_load_to_pipe32(
-    struct atomisp_acc_fw_load_to_pipe *kp,
-    struct atomisp_acc_fw_load_to_pipe32 __user *up)
+static int
+put_atomisp_acc_fw_load_to_pipe32(struct atomisp_acc_fw_load_to_pipe __user *kp,
+				  struct atomisp_acc_fw_load_to_pipe32 __user *up)
 {
-	compat_uptr_t data = (compat_uptr_t)((uintptr_t)kp->data);
+	void __user *data;
 
 	if (!access_ok(up, sizeof(struct atomisp_acc_fw_load_to_pipe32)) ||
-	    put_user(kp->flags, &up->flags) ||
-	    put_user(kp->fw_handle, &up->fw_handle) ||
-	    put_user(kp->size, &up->size) ||
-	    put_user(kp->type, &up->type) ||
-	    put_user(kp->reserved[0], &up->reserved[0]) ||
-	    put_user(kp->reserved[1], &up->reserved[1]) ||
-	    put_user(kp->reserved[2], &up->reserved[2]) ||
-	    put_user(data, &up->data))
+	    assign_in_user(&up->flags, &kp->flags) ||
+	    assign_in_user(&up->fw_handle, &kp->fw_handle) ||
+	    assign_in_user(&up->size, &kp->size) ||
+	    assign_in_user(&up->type, &kp->type) ||
+	    assign_in_user(&up->reserved[0], &kp->reserved[0]) ||
+	    assign_in_user(&up->reserved[1], &kp->reserved[1]) ||
+	    assign_in_user(&up->reserved[2], &kp->reserved[2]) ||
+	    get_user(data, &kp->data) ||
+	    put_user(ptr_to_compat(data), &up->data))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int get_atomisp_sensor_ae_bracketing_lut(
-    struct atomisp_sensor_ae_bracketing_lut *kp,
-    struct atomisp_sensor_ae_bracketing_lut32 __user *up)
+static int
+get_atomisp_sensor_ae_bracketing_lut(struct atomisp_sensor_ae_bracketing_lut __user *kp,
+				     struct atomisp_sensor_ae_bracketing_lut32 __user *up)
 {
 	compat_uptr_t lut;
 
 	if (!access_ok(up, sizeof(struct atomisp_sensor_ae_bracketing_lut32)) ||
-	    get_user(kp->lut_size, &up->lut_size) ||
-	    get_user(lut, &up->lut))
+	    assign_in_user(&kp->lut_size, &up->lut_size) ||
+	    get_user(lut, &up->lut) ||
+	    put_user(compat_ptr(lut), &kp->lut))
 		return -EFAULT;
 
-	kp->lut = (void __force *)compat_ptr(lut);
 	return 0;
 }
 
@@ -848,11 +853,17 @@ static long atomisp_do_compat_ioctl(struct file *file,
 		struct atomisp_metadata md;
 		struct atomisp_metadata_with_type md_with_type;
 		struct atomisp_sensor_ae_bracketing_lut lut;
-	} karg;
-	mm_segment_t old_fs;
+	} __user *karg;
 	void __user *up = compat_ptr(arg);
 	long err = -ENOIOCTLCMD;
 
+	karg = compat_alloc_user_space(
+		sizeof(*karg) + (cmd == ATOMISP_IOC_S_PARAMETERS32 ?
+				 sizeof(struct atomisp_shading_table) +
+				 sizeof(struct atomisp_morph_table) +
+				 sizeof(struct atomisp_dis_coefficients) +
+				 sizeof(struct atomisp_dvs_6axis_config) : 0));
+
 	/* First, convert the command. */
 	switch (cmd) {
 	case ATOMISP_IOC_G_HISTOGRAM32:
@@ -938,130 +949,127 @@ static long atomisp_do_compat_ioctl(struct file *file,
 	switch (cmd) {
 	case ATOMISP_IOC_G_HISTOGRAM:
 	case ATOMISP_IOC_S_HISTOGRAM:
-		err = get_atomisp_histogram32(&karg.his, up);
+		err = get_atomisp_histogram32(&karg->his, up);
 		break;
 	case ATOMISP_IOC_G_DIS_STAT:
-		err = get_atomisp_dis_statistics32(&karg.dis_s, up);
+		err = get_atomisp_dis_statistics32(&karg->dis_s, up);
 		break;
 	case ATOMISP_IOC_S_DIS_COEFS:
-		err = get_atomisp_dis_coefficients32(&karg.dis_c, up);
+		err = get_atomisp_dis_coefficients32(&karg->dis_c, up);
 		break;
 	case ATOMISP_IOC_S_DIS_VECTOR:
-		err = get_atomisp_dvs_6axis_config32(&karg.dvs_c, up);
+		err = get_atomisp_dvs_6axis_config32(&karg->dvs_c, up);
 		break;
 	case ATOMISP_IOC_G_3A_STAT:
-		err = get_atomisp_3a_statistics32(&karg.s3a_s, up);
+		err = get_atomisp_3a_statistics32(&karg->s3a_s, up);
 		break;
 	case ATOMISP_IOC_G_ISP_GDC_TAB:
 	case ATOMISP_IOC_S_ISP_GDC_TAB:
-		err = get_atomisp_morph_table32(&karg.mor_t, up);
+		err = get_atomisp_morph_table32(&karg->mor_t, up);
 		break;
 	case ATOMISP_IOC_S_ISP_FPN_TABLE:
-		err = get_v4l2_framebuffer32(&karg.v4l2_buf, up);
+		err = get_v4l2_framebuffer32(&karg->v4l2_buf, up);
 		break;
 	case ATOMISP_IOC_G_ISP_OVERLAY:
 	case ATOMISP_IOC_S_ISP_OVERLAY:
-		err = get_atomisp_overlay32(&karg.overlay, up);
+		err = get_atomisp_overlay32(&karg->overlay, up);
 		break;
 	case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
-		err = get_atomisp_calibration_group32(&karg.cal_grp, up);
+		err = get_atomisp_calibration_group32(&karg->cal_grp, up);
 		break;
 	case ATOMISP_IOC_ACC_LOAD:
-		err = get_atomisp_acc_fw_load32(&karg.acc_fw_load, up);
+		err = get_atomisp_acc_fw_load32(&karg->acc_fw_load, up);
 		break;
 	case ATOMISP_IOC_ACC_S_ARG:
 	case ATOMISP_IOC_ACC_DESTAB:
-		err = get_atomisp_acc_fw_arg32(&karg.acc_fw_arg, up);
+		err = get_atomisp_acc_fw_arg32(&karg->acc_fw_arg, up);
 		break;
 	case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
 	case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
-		err = get_v4l2_private_int_data32(&karg.v4l2_pri_data, up);
+		err = get_v4l2_private_int_data32(&karg->v4l2_pri_data, up);
 		break;
 	case ATOMISP_IOC_S_ISP_SHD_TAB:
-		err = get_atomisp_shading_table32(&karg.shd_tbl, up);
+		err = get_atomisp_shading_table32(&karg->shd_tbl, up);
 		break;
 	case ATOMISP_IOC_ACC_MAP:
 	case ATOMISP_IOC_ACC_UNMAP:
-		err = get_atomisp_acc_map32(&karg.acc_map, up);
+		err = get_atomisp_acc_map32(&karg->acc_map, up);
 		break;
 	case ATOMISP_IOC_ACC_S_MAPPED_ARG:
-		err = get_atomisp_acc_s_mapped_arg32(&karg.acc_map_arg, up);
+		err = get_atomisp_acc_s_mapped_arg32(&karg->acc_map_arg, up);
 		break;
 	case ATOMISP_IOC_S_PARAMETERS:
-		err = get_atomisp_parameters32(&karg.param, up);
+		err = get_atomisp_parameters32(&karg->param, up);
 		break;
 	case ATOMISP_IOC_ACC_LOAD_TO_PIPE:
-		err = get_atomisp_acc_fw_load_to_pipe32(&karg.acc_fw_to_pipe,
+		err = get_atomisp_acc_fw_load_to_pipe32(&karg->acc_fw_to_pipe,
 							up);
 		break;
 	case ATOMISP_IOC_G_METADATA:
-		err = get_atomisp_metadata_stat32(&karg.md, up);
+		err = get_atomisp_metadata_stat32(&karg->md, up);
 		break;
 	case ATOMISP_IOC_G_METADATA_BY_TYPE:
-		err = get_atomisp_metadata_by_type_stat32(&karg.md_with_type,
-			up);
+		err = get_atomisp_metadata_by_type_stat32(&karg->md_with_type,
+							  up);
 		break;
 	case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
-		err = get_atomisp_sensor_ae_bracketing_lut(&karg.lut, up);
+		err = get_atomisp_sensor_ae_bracketing_lut(&karg->lut, up);
 		break;
 	}
 	if (err)
 		return err;
 
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	err = native_ioctl(file, cmd, (unsigned long)&karg);
-	set_fs(old_fs);
+	err = native_ioctl(file, cmd, (unsigned long)karg);
 	if (err)
 		return err;
 
 	switch (cmd) {
 	case ATOMISP_IOC_G_HISTOGRAM:
-		err = put_atomisp_histogram32(&karg.his, up);
+		err = put_atomisp_histogram32(&karg->his, up);
 		break;
 	case ATOMISP_IOC_G_DIS_STAT:
-		err = put_atomisp_dis_statistics32(&karg.dis_s, up);
+		err = put_atomisp_dis_statistics32(&karg->dis_s, up);
 		break;
 	case ATOMISP_IOC_G_3A_STAT:
-		err = put_atomisp_3a_statistics32(&karg.s3a_s, up);
+		err = put_atomisp_3a_statistics32(&karg->s3a_s, up);
 		break;
 	case ATOMISP_IOC_G_ISP_GDC_TAB:
-		err = put_atomisp_morph_table32(&karg.mor_t, up);
+		err = put_atomisp_morph_table32(&karg->mor_t, up);
 		break;
 	case ATOMISP_IOC_G_ISP_OVERLAY:
-		err = put_atomisp_overlay32(&karg.overlay, up);
+		err = put_atomisp_overlay32(&karg->overlay, up);
 		break;
 	case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
-		err = put_atomisp_calibration_group32(&karg.cal_grp, up);
+		err = put_atomisp_calibration_group32(&karg->cal_grp, up);
 		break;
 	case ATOMISP_IOC_ACC_LOAD:
-		err = put_atomisp_acc_fw_load32(&karg.acc_fw_load, up);
+		err = put_atomisp_acc_fw_load32(&karg->acc_fw_load, up);
 		break;
 	case ATOMISP_IOC_ACC_S_ARG:
 	case ATOMISP_IOC_ACC_DESTAB:
-		err = put_atomisp_acc_fw_arg32(&karg.acc_fw_arg, up);
+		err = put_atomisp_acc_fw_arg32(&karg->acc_fw_arg, up);
 		break;
 	case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
 	case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
-		err = put_v4l2_private_int_data32(&karg.v4l2_pri_data, up);
+		err = put_v4l2_private_int_data32(&karg->v4l2_pri_data, up);
 		break;
 	case ATOMISP_IOC_ACC_MAP:
 	case ATOMISP_IOC_ACC_UNMAP:
-		err = put_atomisp_acc_map32(&karg.acc_map, up);
+		err = put_atomisp_acc_map32(&karg->acc_map, up);
 		break;
 	case ATOMISP_IOC_ACC_S_MAPPED_ARG:
-		err = put_atomisp_acc_s_mapped_arg32(&karg.acc_map_arg, up);
+		err = put_atomisp_acc_s_mapped_arg32(&karg->acc_map_arg, up);
 		break;
 	case ATOMISP_IOC_ACC_LOAD_TO_PIPE:
-		err = put_atomisp_acc_fw_load_to_pipe32(&karg.acc_fw_to_pipe,
+		err = put_atomisp_acc_fw_load_to_pipe32(&karg->acc_fw_to_pipe,
 							up);
 		break;
 	case ATOMISP_IOC_G_METADATA:
-		err = put_atomisp_metadata_stat32(&karg.md, up);
+		err = put_atomisp_metadata_stat32(&karg->md, up);
 		break;
 	case ATOMISP_IOC_G_METADATA_BY_TYPE:
-		err = put_atomisp_metadata_by_type_stat32(&karg.md_with_type,
-			up);
+		err = put_atomisp_metadata_by_type_stat32(&karg->md_with_type,
+							  up);
 		break;
 	}
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] staging: atomisp: Check return value from compat_alloc_user_space
  2020-06-04 16:16 [PATCH 0/4] atomisp set_fs() fix Sakari Ailus
                   ` (2 preceding siblings ...)
  2020-06-04 16:16 ` [PATCH 3/4] staging: atomisp: Fix compat IOCTL handling Sakari Ailus
@ 2020-06-04 16:16 ` Sakari Ailus
  3 siblings, 0 replies; 5+ messages in thread
From: Sakari Ailus @ 2020-06-04 16:16 UTC (permalink / raw)
  To: mchehab; +Cc: linux-media

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
index c8649923b6b9e..e06cf1883fc4b 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c
@@ -863,6 +863,8 @@ static long atomisp_do_compat_ioctl(struct file *file,
 				 sizeof(struct atomisp_morph_table) +
 				 sizeof(struct atomisp_dis_coefficients) +
 				 sizeof(struct atomisp_dvs_6axis_config) : 0));
+	if (!karg)
+		return -ENOMEM;
 
 	/* First, convert the command. */
 	switch (cmd) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-06-04 16:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-04 16:16 [PATCH 0/4] atomisp set_fs() fix Sakari Ailus
2020-06-04 16:16 ` [PATCH 1/4] staging: atomisp: There's no struct atomisp_dvs2_coefficients Sakari Ailus
2020-06-04 16:16 ` [PATCH 2/4] staging: atomisp: Fix atomisp_overlay32 compat handling Sakari Ailus
2020-06-04 16:16 ` [PATCH 3/4] staging: atomisp: Fix compat IOCTL handling Sakari Ailus
2020-06-04 16:16 ` [PATCH 4/4] staging: atomisp: Check return value from compat_alloc_user_space Sakari Ailus

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.