Skip to content

Commit 5e744b2

Browse files
pinchartlrkhuangtao
authored andcommitted
FROMLIST: v4l: async: Move async subdev notifier operations to a separate structure
The async subdev notifier .bound(), .unbind() and .complete() operations are function pointers stored directly in the v4l2_async_subdev structure. As the structure isn't immutable, this creates a potential security risk as the function pointers are mutable. To fix this, move the function pointers to a new v4l2_async_subdev_operations structure that can be made const in drivers. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> (cherry picked from commit ef44d7cb0c00968dc62987a6d0438ec30ca8c06c) https://git.linuxtv.org/sailus/media_tree.git/log/?h=010f7f4393fd http://www.spinics.net/lists/linux-media/msg122688.html Signed-off-by: Marc Herbert <marc.herbert@intel.com> Conflicts: drivers/media/pci/intel/ipu3/ipu3-cio2.c (implement change in non-upstream driver) drivers/media/platform/davinci/vpif_capture.c (Change vpif_probe() instead of newer vpif_capture_get_pdata() UNTESTED) drivers/media/platform/omap3isp/isp.c (Add .bound = isp_subdev_notifier_bound which we still have UNTESTED) drivers/media/platform/atmel/atmel-isc.c drivers/media/platform/atmel/atmel-isi.c drivers/media/platform/pxa_camera.c drivers/media/platform/qcom/camss-8x16/camss.c drivers/media/platform/rcar-vin/rcar-core.c drivers/media/platform/rcar_drif.c drivers/media/platform/stm32/stm32-dcmi.c drivers/media/platform/ti-vpe/cal.c drivers/staging/media/imx/imx-media-dev.c (Ignore drivers we don't have) BUG=b:64133998 TEST=media device topology shows subdevs registered successfully TEST=no camera regression Change-Id: Ic3c4a327763507c8b4fa242ae4642a633e3c7dbc Reviewed-on: https://chromium-review.googlesource.com/693689 Commit-Ready: Tomasz Figa <tfiga@chromium.org> Tested-by: Hyungwoo Yang <hyungwoo.yang@intel.com> Reviewed-by: Tomasz Figa <tfiga@chromium.org> Signed-off-by: Jacob Chen <jacob2.chen@rock-chips.com>
1 parent 01e017d commit 5e744b2

9 files changed

Lines changed: 73 additions & 38 deletions

File tree

drivers/media/platform/am437x/am437x-vpfe.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,6 +2424,11 @@ static int vpfe_async_complete(struct v4l2_async_notifier *notifier)
24242424
return vpfe_probe_complete(vpfe);
24252425
}
24262426

2427+
static const struct v4l2_async_notifier_operations vpfe_async_ops = {
2428+
.bound = vpfe_async_bound,
2429+
.complete = vpfe_async_complete,
2430+
};
2431+
24272432
static struct vpfe_config *
24282433
vpfe_get_pdata(struct platform_device *pdev)
24292434
{
@@ -2597,8 +2602,7 @@ static int vpfe_probe(struct platform_device *pdev)
25972602

25982603
vpfe->notifier.subdevs = vpfe->cfg->asd;
25992604
vpfe->notifier.num_subdevs = ARRAY_SIZE(vpfe->cfg->asd);
2600-
vpfe->notifier.bound = vpfe_async_bound;
2601-
vpfe->notifier.complete = vpfe_async_complete;
2605+
vpfe->notifier.ops = &vpfe_async_ops;
26022606
ret = v4l2_async_notifier_register(&vpfe->v4l2_dev,
26032607
&vpfe->notifier);
26042608
if (ret) {

drivers/media/platform/davinci/vpif_capture.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,6 +1428,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
14281428
return vpif_probe_complete();
14291429
}
14301430

1431+
static const struct v4l2_async_notifier_operations vpif_async_ops = {
1432+
.bound = vpif_async_bound,
1433+
.complete = vpif_async_complete,
1434+
};
1435+
14311436
/**
14321437
* vpif_probe : This function probes the vpif capture driver
14331438
* @pdev: platform device pointer
@@ -1505,8 +1510,7 @@ static __init int vpif_probe(struct platform_device *pdev)
15051510
} else {
15061511
vpif_obj.notifier.subdevs = vpif_obj.config->asd;
15071512
vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0];
1508-
vpif_obj.notifier.bound = vpif_async_bound;
1509-
vpif_obj.notifier.complete = vpif_async_complete;
1513+
vpif_obj.notifier.ops = &vpif_async_ops;
15101514
err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev,
15111515
&vpif_obj.notifier);
15121516
if (err) {

drivers/media/platform/davinci/vpif_display.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
12431243
return vpif_probe_complete();
12441244
}
12451245

1246+
static const struct v4l2_async_notifier_operations vpif_async_ops = {
1247+
.bound = vpif_async_bound,
1248+
.complete = vpif_async_complete,
1249+
};
1250+
12461251
/*
12471252
* vpif_probe: This function creates device entries by register itself to the
12481253
* V4L2 driver and initializes fields of each channel objects
@@ -1316,8 +1321,7 @@ static __init int vpif_probe(struct platform_device *pdev)
13161321
} else {
13171322
vpif_obj.notifier.subdevs = vpif_obj.config->asd;
13181323
vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0];
1319-
vpif_obj.notifier.bound = vpif_async_bound;
1320-
vpif_obj.notifier.complete = vpif_async_complete;
1324+
vpif_obj.notifier.ops = &vpif_async_ops;
13211325
err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev,
13221326
&vpif_obj.notifier);
13231327
if (err) {

drivers/media/platform/exynos4-is/media-dev.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,11 @@ static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
13241324
return ret;
13251325
}
13261326

1327+
static const struct v4l2_async_notifier_operations subdev_notifier_ops = {
1328+
.bound = subdev_notifier_bound,
1329+
.complete = subdev_notifier_complete,
1330+
};
1331+
13271332
static int fimc_md_probe(struct platform_device *pdev)
13281333
{
13291334
struct device *dev = &pdev->dev;
@@ -1411,8 +1416,7 @@ static int fimc_md_probe(struct platform_device *pdev)
14111416
if (fmd->num_sensors > 0) {
14121417
fmd->subdev_notifier.subdevs = fmd->async_subdevs;
14131418
fmd->subdev_notifier.num_subdevs = fmd->num_sensors;
1414-
fmd->subdev_notifier.bound = subdev_notifier_bound;
1415-
fmd->subdev_notifier.complete = subdev_notifier_complete;
1419+
fmd->subdev_notifier.ops = &subdev_notifier_ops;
14161420
fmd->num_sensors = 0;
14171421

14181422
ret = v4l2_async_notifier_register(&fmd->v4l2_dev,

drivers/media/platform/omap3isp/isp.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,6 +2307,11 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
23072307
return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
23082308
}
23092309

2310+
static const struct v4l2_async_notifier_operations isp_subdev_notifier_ops = {
2311+
.complete = isp_subdev_notifier_complete,
2312+
.bound = isp_subdev_notifier_bound,
2313+
};
2314+
23102315
/*
23112316
* isp_probe - Probe ISP platform device
23122317
* @pdev: Pointer to ISP platform device
@@ -2470,8 +2475,7 @@ static int isp_probe(struct platform_device *pdev)
24702475
if (ret < 0)
24712476
goto error_modules;
24722477

2473-
isp->notifier.bound = isp_subdev_notifier_bound;
2474-
isp->notifier.complete = isp_subdev_notifier_complete;
2478+
isp->notifier.ops = &isp_subdev_notifier_ops;
24752479

24762480
ret = v4l2_async_notifier_register(&isp->v4l2_dev, &isp->notifier);
24772481
if (ret)

drivers/media/platform/soc_camera/soc_camera.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,12 @@ static int soc_camera_async_complete(struct v4l2_async_notifier *notifier)
17351735
return 0;
17361736
}
17371737

1738+
static const struct v4l2_async_notifier_operations soc_camera_async_ops = {
1739+
.bound = soc_camera_async_bound,
1740+
.unbind = soc_camera_async_unbind,
1741+
.complete = soc_camera_async_complete,
1742+
};
1743+
17381744
static int scan_async_group(struct soc_camera_host *ici,
17391745
struct v4l2_async_subdev **asd, unsigned int size)
17401746
{
@@ -1781,9 +1787,7 @@ static int scan_async_group(struct soc_camera_host *ici,
17811787

17821788
sasc->notifier.subdevs = asd;
17831789
sasc->notifier.num_subdevs = size;
1784-
sasc->notifier.bound = soc_camera_async_bound;
1785-
sasc->notifier.unbind = soc_camera_async_unbind;
1786-
sasc->notifier.complete = soc_camera_async_complete;
1790+
sasc->notifier.ops = &soc_camera_async_ops;
17871791

17881792
icd->sasc = sasc;
17891793
icd->parent = ici->v4l2_dev.dev;
@@ -1880,9 +1884,7 @@ static int soc_of_bind(struct soc_camera_host *ici,
18801884

18811885
sasc->notifier.subdevs = &info->subdev;
18821886
sasc->notifier.num_subdevs = 1;
1883-
sasc->notifier.bound = soc_camera_async_bound;
1884-
sasc->notifier.unbind = soc_camera_async_unbind;
1885-
sasc->notifier.complete = soc_camera_async_complete;
1887+
sasc->notifier.ops = &soc_camera_async_ops;
18861888

18871889
icd->sasc = sasc;
18881890
icd->parent = ici->v4l2_dev.dev;

drivers/media/platform/xilinx/xilinx-vipp.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,11 @@ static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier,
352352
return -EINVAL;
353353
}
354354

355+
static const struct v4l2_async_notifier_operations xvip_graph_notify_ops = {
356+
.bound = xvip_graph_notify_bound,
357+
.complete = xvip_graph_notify_complete,
358+
};
359+
355360
static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
356361
struct device_node *node)
357362
{
@@ -552,8 +557,7 @@ static int xvip_graph_init(struct xvip_composite_device *xdev)
552557

553558
xdev->notifier.subdevs = subdevs;
554559
xdev->notifier.num_subdevs = num_subdevs;
555-
xdev->notifier.bound = xvip_graph_notify_bound;
556-
xdev->notifier.complete = xvip_graph_notify_complete;
560+
xdev->notifier.ops = &xvip_graph_notify_ops;
557561

558562
ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier);
559563
if (ret < 0) {

drivers/media/v4l2-core/v4l2-async.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,16 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
106106
{
107107
int ret;
108108

109-
if (notifier->bound) {
110-
ret = notifier->bound(notifier, sd, asd);
109+
if (notifier->ops->bound) {
110+
ret = notifier->ops->bound(notifier, sd, asd);
111111
if (ret < 0)
112112
return ret;
113113
}
114114

115115
ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
116116
if (ret < 0) {
117-
if (notifier->unbind)
118-
notifier->unbind(notifier, sd, asd);
117+
if (notifier->ops->unbind)
118+
notifier->ops->unbind(notifier, sd, asd);
119119
return ret;
120120
}
121121

@@ -127,8 +127,8 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
127127
/* Move from the global subdevice list to notifier's done */
128128
list_move(&sd->async_list, &notifier->done);
129129

130-
if (list_empty(&notifier->waiting) && notifier->complete)
131-
return notifier->complete(notifier);
130+
if (list_empty(&notifier->waiting) && notifier->ops->complete)
131+
return notifier->ops->complete(notifier);
132132

133133
return 0;
134134
}
@@ -214,8 +214,8 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
214214
list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {
215215
v4l2_async_cleanup(sd);
216216

217-
if (notifier->unbind)
218-
notifier->unbind(notifier, sd, sd->asd);
217+
if (notifier->ops->unbind)
218+
notifier->ops->unbind(notifier, sd, sd->asd);
219219

220220
list_move(&sd->async_list, &subdev_list);
221221
}
@@ -306,8 +306,8 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
306306

307307
v4l2_async_cleanup(sd);
308308

309-
if (notifier->unbind)
310-
notifier->unbind(notifier, sd, sd->asd);
309+
if (notifier->ops->unbind)
310+
notifier->ops->unbind(notifier, sd, sd->asd);
311311

312312
mutex_unlock(&list_lock);
313313
}

include/media/v4l2-async.h

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct device;
1818
struct device_node;
1919
struct v4l2_device;
2020
struct v4l2_subdev;
21+
struct v4l2_async_notifier;
2122

2223
/* A random max subdevice number, used to allocate an array on stack */
2324
#define V4L2_MAX_SUBDEVS 128U
@@ -78,35 +79,43 @@ struct v4l2_async_subdev {
7879
struct list_head list;
7980
};
8081

82+
/**
83+
* struct v4l2_async_notifier_operations - Asynchronous V4L2 notifier operations
84+
* @bound: a subdevice driver has successfully probed one of the subdevices
85+
* @complete: all subdevices have been probed successfully
86+
* @unbind: a subdevice is leaving
87+
*/
88+
struct v4l2_async_notifier_operations {
89+
int (*bound)(struct v4l2_async_notifier *notifier,
90+
struct v4l2_subdev *subdev,
91+
struct v4l2_async_subdev *asd);
92+
int (*complete)(struct v4l2_async_notifier *notifier);
93+
void (*unbind)(struct v4l2_async_notifier *notifier,
94+
struct v4l2_subdev *subdev,
95+
struct v4l2_async_subdev *asd);
96+
};
97+
8198
/**
8299
* struct v4l2_async_notifier - v4l2_device notifier data
83100
*
101+
* @ops: notifier operations
84102
* @num_subdevs: number of subdevices used in the subdevs array
85103
* @max_subdevs: number of subdevices allocated in the subdevs array
86104
* @subdevs: array of pointers to subdevice descriptors
87105
* @v4l2_dev: pointer to struct v4l2_device
88106
* @waiting: list of struct v4l2_async_subdev, waiting for their drivers
89107
* @done: list of struct v4l2_subdev, already probed
90108
* @list: member in a global list of notifiers
91-
* @bound: a subdevice driver has successfully probed one of subdevices
92-
* @complete: all subdevices have been probed successfully
93-
* @unbind: a subdevice is leaving
94109
*/
95110
struct v4l2_async_notifier {
111+
const struct v4l2_async_notifier_operations *ops;
96112
unsigned int num_subdevs;
97113
unsigned int max_subdevs;
98114
struct v4l2_async_subdev **subdevs;
99115
struct v4l2_device *v4l2_dev;
100116
struct list_head waiting;
101117
struct list_head done;
102118
struct list_head list;
103-
int (*bound)(struct v4l2_async_notifier *notifier,
104-
struct v4l2_subdev *subdev,
105-
struct v4l2_async_subdev *asd);
106-
int (*complete)(struct v4l2_async_notifier *notifier);
107-
void (*unbind)(struct v4l2_async_notifier *notifier,
108-
struct v4l2_subdev *subdev,
109-
struct v4l2_async_subdev *asd);
110119
};
111120

112121
/**

0 commit comments

Comments
 (0)