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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 329aeeb..68606af 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -18,6 +18,7 @@ struct device;
 struct device_node;
 struct v4l2_device;
 struct v4l2_subdev;
+struct v4l2_async_notifier;
 
 /* A random max subdevice number, used to allocate an array on stack */
 #define V4L2_MAX_SUBDEVS 128U
@@ -79,27 +80,12 @@ struct v4l2_async_subdev {
 };
 
 /**
- * struct v4l2_async_notifier - v4l2_device notifier data
- *
- * @num_subdevs: number of subdevices used in the subdevs array
- * @max_subdevs: number of subdevices allocated in the subdevs array
- * @subdevs:	array of pointers to subdevice descriptors
- * @v4l2_dev:	pointer to struct v4l2_device
- * @waiting:	list of struct v4l2_async_subdev, waiting for their drivers
- * @done:	list of struct v4l2_subdev, already probed
- * @list:	member in a global list of notifiers
- * @bound:	a subdevice driver has successfully probed one of subdevices
+ * struct v4l2_async_notifier_operations - Asynchronous V4L2 notifier operations
+ * @bound:	a subdevice driver has successfully probed one of the subdevices
  * @complete:	all subdevices have been probed successfully
  * @unbind:	a subdevice is leaving
  */
-struct v4l2_async_notifier {
-	unsigned int num_subdevs;
-	unsigned int max_subdevs;
-	struct v4l2_async_subdev **subdevs;
-	struct v4l2_device *v4l2_dev;
-	struct list_head waiting;
-	struct list_head done;
-	struct list_head list;
+struct v4l2_async_notifier_operations {
 	int (*bound)(struct v4l2_async_notifier *notifier,
 		     struct v4l2_subdev *subdev,
 		     struct v4l2_async_subdev *asd);
@@ -110,6 +96,29 @@ struct v4l2_async_notifier {
 };
 
 /**
+ * struct v4l2_async_notifier - v4l2_device notifier data
+ *
+ * @ops:	notifier operations
+ * @num_subdevs: number of subdevices used in the subdevs array
+ * @max_subdevs: number of subdevices allocated in the subdevs array
+ * @subdevs:	array of pointers to subdevice descriptors
+ * @v4l2_dev:	pointer to struct v4l2_device
+ * @waiting:	list of struct v4l2_async_subdev, waiting for their drivers
+ * @done:	list of struct v4l2_subdev, already probed
+ * @list:	member in a global list of notifiers
+ */
+struct v4l2_async_notifier {
+	const struct v4l2_async_notifier_operations *ops;
+	unsigned int num_subdevs;
+	unsigned int max_subdevs;
+	struct v4l2_async_subdev **subdevs;
+	struct v4l2_device *v4l2_dev;
+	struct list_head waiting;
+	struct list_head done;
+	struct list_head list;
+};
+
+/**
  * v4l2_async_notifier_register - registers a subdevice asynchronous notifier
  *
  * @v4l2_dev: pointer to &struct v4l2_device