From 743a5139b22023b81ebaa62e4423d5ebe83a363f Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Thu, 8 Sep 2022 00:47:16 +0200 Subject: [PATCH] Update v5.19 patches Changes: - Replace previous fix for NULL pointer error in IPU3 (cameras) with a proper fix based on feedback from the mailing list. Links: - kernel: https://github.com/linux-surface/kernel/commit/ab70f2e8b1a361bafd428cbd25b8c2e6636a1de8 --- patches/5.19/0010-cameras.patch | 259 +++++++++++++++++++++++-------- patches/5.19/0011-amd-gpio.patch | 4 +- 2 files changed, 200 insertions(+), 63 deletions(-) diff --git a/patches/5.19/0010-cameras.patch b/patches/5.19/0010-cameras.patch index 543d39db6..abfed3c6f 100644 --- a/patches/5.19/0010-cameras.patch +++ b/patches/5.19/0010-cameras.patch @@ -892,7 +892,7 @@ index d0715144bf3e..3a25dfc696b2 100644 -- 2.37.3 -From bbf4e826699ddad5cfbb6ac819954944c2625db4 Mon Sep 17 00:00:00 2001 +From 5f9948f9d56e88e3470b9211ff907f9dd4bb863e Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Fri, 15 Jul 2022 23:48:00 +0200 Subject: [PATCH] drivers/media/i2c: Fix DW9719 dependencies @@ -921,78 +921,215 @@ index 5c245f642ae3..50ea62e63784 100644 -- 2.37.3 -From dfdc9ca59f2aee9b4b6ae76e0f3ae7b51d617335 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz -Date: Wed, 7 Sep 2022 12:40:24 +0200 -Subject: [PATCH] media: staging/intel-ipu3: Finalize subdev initialization to - allcoate active state +From 521442f66a874ea64aaab70cdf707aa11dc270d5 Mon Sep 17 00:00:00 2001 +From: Sakari Ailus +Date: Thu, 25 Aug 2022 21:36:37 +0300 +Subject: [PATCH] ipu3-imgu: Fix NULL pointer dereference in active selection + access -Commit f69952a4dc1e ("media: subdev: add active state to struct -v4l2_subdev") introduced the active_state member to struct v4l2_subdev. -This state needs to be allocated via v4l2_subdev_init_finalize(). The -intel-ipu3 driver unfortunately does not do that, due to which, -active_state is NULL and we run into an oops (NULL pointer dereference) -when that state is accessed. +What the IMGU driver did was that it first acquired the pointers to active +and try V4L2 subdev state, and only then figured out which one to use. -In particular, this happens subdev in IOCTLs as commit 3cc7a4bbc381 -("media: subdev: pass also the active state to subdevs from ioctls") -passes that state on to the subdev IOCTLs. An example scenario where -this happens is running libcamera's qcam or cam on a device with IPU3, -for example the Microsoft Surface Book 2. In this case, the oops is -reproducibly in v4l2_subdev_get_try_crop(), called via -imgu_subdev_set_selection(). +The problem with that approach and a later patch (see Fixes: tag) is that +as sd_state argument to v4l2_subdev_get_try_crop() et al is NULL, there is +now an attempt to dereference that. -To fix this, allocate the active_state member via -v4l2_subdev_init_finalize(). +Fix this. -Link: https://github.com/linux-surface/linux-surface/issues/907 -Fixes: 3cc7a4bbc381 ("media: subdev: pass also the active state to subdevs from ioctls") -Signed-off-by: Maximilian Luz +Also rewrap lines a little. + +Fixes: 0d346d2a6f54 ("media: v4l2-subdev: add subdev-wide state struct") +Cc: stable@vger.kernel.org # for v5.14 and later +Signed-off-by: Sakari Ailus +Reviewed-by: Bingbu Cao Patchset: cameras --- - drivers/staging/media/ipu3/ipu3-v4l2.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) + drivers/staging/media/ipu3/ipu3-v4l2.c | 31 ++++++++++++-------------- + 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c -index d1c539cefba8..84ab98ba9a2e 100644 +index d1c539cefba8..2234bb8d48b3 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c -@@ -1093,10 +1093,18 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu, - "failed to create subdev v4l2 ctrl with err %d", r); - goto fail_subdev; +@@ -192,33 +192,30 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_selection *sel) + { +- struct v4l2_rect *try_sel, *r; +- struct imgu_v4l2_subdev *imgu_sd = container_of(sd, +- struct imgu_v4l2_subdev, +- subdev); ++ struct imgu_v4l2_subdev *imgu_sd = ++ container_of(sd, struct imgu_v4l2_subdev, subdev); + + if (sel->pad != IMGU_NODE_IN) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: +- try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad); +- r = &imgu_sd->rect.eff; +- break; ++ if (sel->which == V4L2_SUBDEV_FORMAT_TRY) ++ sel->r = *v4l2_subdev_get_try_crop(sd, sd_state, ++ sel->pad); ++ else ++ sel->r = imgu_sd->rect.eff; ++ return 0; + case V4L2_SEL_TGT_COMPOSE: +- try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad); +- r = &imgu_sd->rect.bds; +- break; ++ if (sel->which == V4L2_SUBDEV_FORMAT_TRY) ++ sel->r = *v4l2_subdev_get_try_compose(sd, sd_state, ++ sel->pad); ++ else ++ sel->r = imgu_sd->rect.bds; ++ return 0; + default: + return -EINVAL; } -+ -+ r = v4l2_subdev_init_finalize(&imgu_sd->subdev); -+ if (r) { -+ dev_err(&imgu->pci_dev->dev, -+ "failed to initialize subdev (%d)\n", r); -+ goto fail_subdev; -+ } -+ - r = v4l2_device_register_subdev(&imgu->v4l2_dev, &imgu_sd->subdev); - if (r) { - dev_err(&imgu->pci_dev->dev, -- "failed initialize subdev (%d)\n", r); -+ "failed to register subdev (%d)\n", r); - goto fail_subdev; - } - -@@ -1104,6 +1112,7 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu, - return 0; - - fail_subdev: -+ v4l2_subdev_cleanup(&imgu_sd->subdev); - v4l2_ctrl_handler_free(imgu_sd->subdev.ctrl_handler); - media_entity_cleanup(&imgu_sd->subdev.entity); - -@@ -1275,6 +1284,7 @@ static void imgu_v4l2_subdev_cleanup(struct imgu_device *imgu, unsigned int i) - struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[i]; - - v4l2_device_unregister_subdev(&imgu_pipe->imgu_sd.subdev); -+ v4l2_subdev_cleanup(&imgu_pipe->imgu_sd.subdev); - v4l2_ctrl_handler_free(imgu_pipe->imgu_sd.subdev.ctrl_handler); - media_entity_cleanup(&imgu_pipe->imgu_sd.subdev.entity); +- +- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) +- sel->r = *try_sel; +- else +- sel->r = *r; +- +- return 0; } + + static int imgu_subdev_set_selection(struct v4l2_subdev *sd, +-- +2.37.3 + +From fd8017575c3e5896d2fdb30f0c6d9af49b3cf1b4 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Wed, 7 Sep 2022 15:38:08 +0200 +Subject: [PATCH] ipu3-imgu: Fix NULL pointer dereference in + imgu_subdev_set_selection() + +Calling v4l2_subdev_get_try_crop() and v4l2_subdev_get_try_compose() +with a subdev state of NULL leads to a NULL pointer dereference. This +can currently happen in imgu_subdev_set_selection() when the state +passed in is NULL, as this method first gets pointers to both the "try" +and "active" states and only then decides which to use. + +The same issue has been addressed for imgu_subdev_get_selection() with +commit 30d03a0de650 ("ipu3-imgu: Fix NULL pointer dereference in active +selection access"). However the issue still persists in +imgu_subdev_set_selection(). + +Therefore, apply a similar fix as done in the aforementioned commit to +imgu_subdev_set_selection(). To keep things a bit cleaner, introduce +helper functions for "crop" and "compose" access and use them in both +imgu_subdev_set_selection() and imgu_subdev_get_selection(). + +Fixes: 0d346d2a6f54 ("media: v4l2-subdev: add subdev-wide state struct") +Cc: stable@vger.kernel.org # for v5.14 and later +Signed-off-by: Maximilian Luz +Patchset: cameras +--- + drivers/staging/media/ipu3/ipu3-v4l2.c | 57 +++++++++++++++----------- + 1 file changed, 34 insertions(+), 23 deletions(-) + +diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c +index 2234bb8d48b3..490ba0eb249b 100644 +--- a/drivers/staging/media/ipu3/ipu3-v4l2.c ++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c +@@ -188,6 +188,28 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd, + return 0; + } + ++static struct v4l2_rect * ++imgu_subdev_get_crop(struct imgu_v4l2_subdev *sd, ++ struct v4l2_subdev_state *sd_state, unsigned int pad, ++ enum v4l2_subdev_format_whence which) ++{ ++ if (which == V4L2_SUBDEV_FORMAT_TRY) ++ return v4l2_subdev_get_try_crop(&sd->subdev, sd_state, pad); ++ else ++ return &sd->rect.eff; ++} ++ ++static struct v4l2_rect * ++imgu_subdev_get_compose(struct imgu_v4l2_subdev *sd, ++ struct v4l2_subdev_state *sd_state, unsigned int pad, ++ enum v4l2_subdev_format_whence which) ++{ ++ if (which == V4L2_SUBDEV_FORMAT_TRY) ++ return v4l2_subdev_get_try_compose(&sd->subdev, sd_state, pad); ++ else ++ return &sd->rect.bds; ++} ++ + static int imgu_subdev_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_selection *sel) +@@ -200,18 +222,12 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd, + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: +- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) +- sel->r = *v4l2_subdev_get_try_crop(sd, sd_state, +- sel->pad); +- else +- sel->r = imgu_sd->rect.eff; ++ sel->r = *imgu_subdev_get_crop(imgu_sd, sd_state, sel->pad, ++ sel->which); + return 0; + case V4L2_SEL_TGT_COMPOSE: +- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) +- sel->r = *v4l2_subdev_get_try_compose(sd, sd_state, +- sel->pad); +- else +- sel->r = imgu_sd->rect.bds; ++ sel->r = *imgu_subdev_get_compose(imgu_sd, sd_state, sel->pad, ++ sel->which); + return 0; + default: + return -EINVAL; +@@ -223,10 +239,9 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_selection *sel) + { + struct imgu_device *imgu = v4l2_get_subdevdata(sd); +- struct imgu_v4l2_subdev *imgu_sd = container_of(sd, +- struct imgu_v4l2_subdev, +- subdev); +- struct v4l2_rect *rect, *try_sel; ++ struct imgu_v4l2_subdev *imgu_sd = ++ container_of(sd, struct imgu_v4l2_subdev, subdev); ++ struct v4l2_rect *rect; + + dev_dbg(&imgu->pci_dev->dev, + "set subdev %u sel which %u target 0x%4x rect [%ux%u]", +@@ -238,22 +253,18 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd, + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: +- try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad); +- rect = &imgu_sd->rect.eff; ++ rect = imgu_subdev_get_crop(imgu_sd, sd_state, sel->pad, ++ sel->which); + break; + case V4L2_SEL_TGT_COMPOSE: +- try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad); +- rect = &imgu_sd->rect.bds; ++ rect = imgu_subdev_get_compose(imgu_sd, sd_state, sel->pad, ++ sel->which); + break; + default: + return -EINVAL; + } + +- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) +- *try_sel = sel->r; +- else +- *rect = sel->r; +- ++ *rect = sel->r; + return 0; + } + -- 2.37.3 diff --git a/patches/5.19/0011-amd-gpio.patch b/patches/5.19/0011-amd-gpio.patch index ef7780fb7..ff0c12248 100644 --- a/patches/5.19/0011-amd-gpio.patch +++ b/patches/5.19/0011-amd-gpio.patch @@ -1,4 +1,4 @@ -From ceacc22113c3e2b32c823b5e7a282827e867f46b Mon Sep 17 00:00:00 2001 +From 76d50aaa6179b1f53d8c75c045c59982ef0599c7 Mon Sep 17 00:00:00 2001 From: Sachi King Date: Sat, 29 May 2021 17:47:38 +1000 Subject: [PATCH] ACPI: Add quirk for Surface Laptop 4 AMD missing irq 7 @@ -65,7 +65,7 @@ index 907cc98b1938..0116d27b29ea 100644 -- 2.37.3 -From e62553a30f988d97e850348bacaf6e9049c5d113 Mon Sep 17 00:00:00 2001 +From bc8e14285b0b08caebc7b27b199ca09d6f64a17a Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Thu, 3 Jun 2021 14:04:26 +0200 Subject: [PATCH] ACPI: Add AMD 13" Surface Laptop 4 model to irq 7 override