Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6ee3f0d authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

media: 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: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Acked-by: default avatarNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: default avatarSebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent bce9e317
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -2417,6 +2417,11 @@ static int vpfe_async_complete(struct v4l2_async_notifier *notifier)
	return vpfe_probe_complete(vpfe);
}

static const struct v4l2_async_notifier_operations vpfe_async_ops = {
	.bound = vpfe_async_bound,
	.complete = vpfe_async_complete,
};

static struct vpfe_config *
vpfe_get_pdata(struct platform_device *pdev)
{
@@ -2590,8 +2595,7 @@ static int vpfe_probe(struct platform_device *pdev)

	vpfe->notifier.subdevs = vpfe->cfg->asd;
	vpfe->notifier.num_subdevs = ARRAY_SIZE(vpfe->cfg->asd);
	vpfe->notifier.bound = vpfe_async_bound;
	vpfe->notifier.complete = vpfe_async_complete;
	vpfe->notifier.ops = &vpfe_async_ops;
	ret = v4l2_async_notifier_register(&vpfe->v4l2_dev,
						&vpfe->notifier);
	if (ret) {
+7 −3
Original line number Diff line number Diff line
@@ -1979,6 +1979,12 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
	return 0;
}

static const struct v4l2_async_notifier_operations isc_async_ops = {
	.bound = isc_async_bound,
	.unbind = isc_async_unbind,
	.complete = isc_async_complete,
};

static void isc_subdev_cleanup(struct isc_device *isc)
{
	struct isc_subdev_entity *subdev_entity;
@@ -2203,9 +2209,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
	list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
		subdev_entity->notifier.subdevs = &subdev_entity->asd;
		subdev_entity->notifier.num_subdevs = 1;
		subdev_entity->notifier.bound = isc_async_bound;
		subdev_entity->notifier.unbind = isc_async_unbind;
		subdev_entity->notifier.complete = isc_async_complete;
		subdev_entity->notifier.ops = &isc_async_ops;

		ret = v4l2_async_notifier_register(&isc->v4l2_dev,
						   &subdev_entity->notifier);
+7 −3
Original line number Diff line number Diff line
@@ -1103,6 +1103,12 @@ static int isi_graph_notify_bound(struct v4l2_async_notifier *notifier,
	return 0;
}

static const struct v4l2_async_notifier_operations isi_graph_notify_ops = {
	.bound = isi_graph_notify_bound,
	.unbind = isi_graph_notify_unbind,
	.complete = isi_graph_notify_complete,
};

static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
{
	struct device_node *ep = NULL;
@@ -1150,9 +1156,7 @@ static int isi_graph_init(struct atmel_isi *isi)

	isi->notifier.subdevs = subdevs;
	isi->notifier.num_subdevs = 1;
	isi->notifier.bound = isi_graph_notify_bound;
	isi->notifier.unbind = isi_graph_notify_unbind;
	isi->notifier.complete = isi_graph_notify_complete;
	isi->notifier.ops = &isi_graph_notify_ops;

	ret = v4l2_async_notifier_register(&isi->v4l2_dev, &isi->notifier);
	if (ret < 0) {
+6 −2
Original line number Diff line number Diff line
@@ -1500,6 +1500,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
	return vpif_probe_complete();
}

static const struct v4l2_async_notifier_operations vpif_async_ops = {
	.bound = vpif_async_bound,
	.complete = vpif_async_complete,
};

static struct vpif_capture_config *
vpif_capture_get_pdata(struct platform_device *pdev)
{
@@ -1691,8 +1696,7 @@ static __init int vpif_probe(struct platform_device *pdev)
	} else {
		vpif_obj.notifier.subdevs = vpif_obj.config->asd;
		vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0];
		vpif_obj.notifier.bound = vpif_async_bound;
		vpif_obj.notifier.complete = vpif_async_complete;
		vpif_obj.notifier.ops = &vpif_async_ops;
		err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev,
						   &vpif_obj.notifier);
		if (err) {
+6 −2
Original line number Diff line number Diff line
@@ -1232,6 +1232,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
	return vpif_probe_complete();
}

static const struct v4l2_async_notifier_operations vpif_async_ops = {
	.bound = vpif_async_bound,
	.complete = vpif_async_complete,
};

/*
 * vpif_probe: This function creates device entries by register itself to the
 * V4L2 driver and initializes fields of each channel objects
@@ -1313,8 +1318,7 @@ static __init int vpif_probe(struct platform_device *pdev)
	} else {
		vpif_obj.notifier.subdevs = vpif_obj.config->asd;
		vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0];
		vpif_obj.notifier.bound = vpif_async_bound;
		vpif_obj.notifier.complete = vpif_async_complete;
		vpif_obj.notifier.ops = &vpif_async_ops;
		err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev,
						   &vpif_obj.notifier);
		if (err) {
Loading