iio: Don't silently expect attribute types
authorMatti Vaittinen <mazziesaccount@gmail.com>
Mon, 3 Oct 2022 08:13:53 +0000 (11:13 +0300)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Wed, 23 Nov 2022 19:44:04 +0000 (19:44 +0000)
The iio_triggered_buffer_setup_ext() and the
devm_iio_kfifo_buffer_setup_ext() were changed by
commit 15097c7a1adc ("iio: buffer: wrap all buffer attributes into iio_dev_attr")
to silently expect that all attributes given in buffer_attrs array are
device-attributes. This expectation was not forced by the API - and some
drivers did register attributes created by IIO_CONST_ATTR().

When using IIO_CONST_ATTRs the added attribute "wrapping" does not copy
the pointer to stored string constant and when the sysfs file is read the
kernel will access to invalid location.

Change the function signatures to expect an array of iio_dev_attrs to
avoid similar errors in the future.

Merge conflict resolved whilst applying due to patch crossing with
two new drivers (kx022a accelerometer and ad4130 ADC).

Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
Tested-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Link: https://lore.kernel.org/r/63f54787a684eb1232f1c5d275a09c786987fe4a.1664782676.git.mazziesaccount@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
15 files changed:
drivers/iio/accel/adxl367.c
drivers/iio/accel/adxl372.c
drivers/iio/accel/bmc150-accel-core.c
drivers/iio/accel/kionix-kx022a.c
drivers/iio/adc/ad4130.c
drivers/iio/adc/at91-sama5d2_adc.c
drivers/iio/buffer/industrialio-buffer-dmaengine.c
drivers/iio/buffer/industrialio-triggered-buffer.c
drivers/iio/buffer/kfifo_buf.c
drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
drivers/iio/industrialio-buffer.c
include/linux/iio/buffer_impl.h
include/linux/iio/kfifo_buf.h
include/linux/iio/triggered_buffer.h

index d8e98f65f25dfad8dd5ff3e68aacd427a7485e2f..90b7ae6d42b7700c9cb0a328b093352a7cec419e 100644 (file)
@@ -1191,11 +1191,11 @@ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
 static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
                       adxl367_get_fifo_enabled, NULL, 0);
 
-static const struct attribute *adxl367_fifo_attributes[] = {
-       &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+static const struct iio_dev_attr *adxl367_fifo_attributes[] = {
+       &iio_dev_attr_hwfifo_watermark_min,
+       &iio_dev_attr_hwfifo_watermark_max,
+       &iio_dev_attr_hwfifo_watermark,
+       &iio_dev_attr_hwfifo_enabled,
        NULL,
 };
 
index 90e1d726b9c5907322aaa2f21e53df3249b728c4..c4193286eb0538e51c6741f32612807c9d8068fc 100644 (file)
@@ -1006,11 +1006,11 @@ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
 static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
                       adxl372_get_fifo_enabled, NULL, 0);
 
-static const struct attribute *adxl372_fifo_attributes[] = {
-       &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+static const struct iio_dev_attr *adxl372_fifo_attributes[] = {
+       &iio_dev_attr_hwfifo_watermark_min,
+       &iio_dev_attr_hwfifo_watermark_max,
+       &iio_dev_attr_hwfifo_watermark,
+       &iio_dev_attr_hwfifo_enabled,
        NULL,
 };
 
index b4a077944896786503fd0e97254ea325abebff94..110591804b4c4fd5b3407e8b83d9b35ddf10b652 100644 (file)
@@ -933,11 +933,11 @@ static IIO_DEVICE_ATTR(hwfifo_enabled, S_IRUGO,
 static IIO_DEVICE_ATTR(hwfifo_watermark, S_IRUGO,
                       bmc150_accel_get_fifo_watermark, NULL, 0);
 
-static const struct attribute *bmc150_accel_fifo_attributes[] = {
-       &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+static const struct iio_dev_attr *bmc150_accel_fifo_attributes[] = {
+       &iio_dev_attr_hwfifo_watermark_min,
+       &iio_dev_attr_hwfifo_watermark_max,
+       &iio_dev_attr_hwfifo_watermark,
+       &iio_dev_attr_hwfifo_enabled,
        NULL,
 };
 
@@ -1665,7 +1665,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
                            enum bmc150_type type, const char *name,
                            bool block_supported)
 {
-       const struct attribute **fifo_attrs;
+       const struct iio_dev_attr **fifo_attrs;
        struct bmc150_accel_data *data;
        struct iio_dev *indio_dev;
        int ret;
index 50de7f9a1cc7f98a19635c3821a146ae3596a24f..f866859855cddc9433a421829b023952808013c8 100644 (file)
@@ -575,9 +575,9 @@ static ssize_t hwfifo_watermark_show(struct device *dev,
 static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0);
 static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0);
 
-static const struct attribute *kx022a_fifo_attributes[] = {
-       &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+static const struct iio_dev_attr *kx022a_fifo_attributes[] = {
+       &iio_dev_attr_hwfifo_watermark,
+       &iio_dev_attr_hwfifo_enabled,
        NULL
 };
 
index ae1a4dd5c40ad88fe024a19eb04aafb6b9b8546f..38394341fd6e7401a94662fd5524eb512ea402b4 100644 (file)
@@ -1380,11 +1380,11 @@ static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
 static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0);
 static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0);
 
-static const struct attribute *ad4130_fifo_attributes[] = {
-       &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+static const struct iio_dev_attr *ad4130_fifo_attributes[] = {
+       &iio_dev_attr_hwfifo_watermark_min,
+       &iio_dev_attr_hwfifo_watermark_max,
+       &iio_dev_attr_hwfifo_watermark,
+       &iio_dev_attr_hwfifo_enabled,
        NULL
 };
 
index aa2e1640c4a3cafa249b7dc904b4065c88490e60..a00b8316a12f2c04cd1a135399a9aa23e2518f56 100644 (file)
@@ -2201,11 +2201,11 @@ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
 IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "2");
 IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, AT91_HWFIFO_MAX_SIZE_STR);
 
-static const struct attribute *at91_adc_fifo_attributes[] = {
-       &iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+static const struct iio_dev_attr *at91_adc_fifo_attributes[] = {
+       &iio_dev_attr_hwfifo_watermark_min,
+       &iio_dev_attr_hwfifo_watermark_max,
+       &iio_dev_attr_hwfifo_watermark,
+       &iio_dev_attr_hwfifo_enabled,
        NULL,
 };
 
@@ -2222,7 +2222,7 @@ static int at91_adc_buffer_and_trigger_init(struct device *dev,
                                            struct iio_dev *indio)
 {
        struct at91_adc_state *st = iio_priv(indio);
-       const struct attribute **fifo_attrs;
+       const struct iio_dev_attr **fifo_attrs;
        int ret;
 
        if (st->selected_trig->hw_trig)
index f744b62a636ad5ef526cd9e6b981b2a729fbe288..5f85ba38e6f6e7a052ebd59b2aa5a0aed14d6bf4 100644 (file)
@@ -142,8 +142,8 @@ static ssize_t iio_dmaengine_buffer_get_length_align(struct device *dev,
 static IIO_DEVICE_ATTR(length_align_bytes, 0444,
                       iio_dmaengine_buffer_get_length_align, NULL, 0);
 
-static const struct attribute *iio_dmaengine_buffer_attrs[] = {
-       &iio_dev_attr_length_align_bytes.dev_attr.attr,
+static const struct iio_dev_attr *iio_dmaengine_buffer_attrs[] = {
+       &iio_dev_attr_length_align_bytes,
        NULL,
 };
 
index 8d4fc97d100598230b2ed1c02fa37c1ae11e45ca..c7671b1f5eadacf262b0ab62be176ef0e6751a70 100644 (file)
@@ -41,7 +41,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev,
        irqreturn_t (*thread)(int irq, void *p),
        enum iio_buffer_direction direction,
        const struct iio_buffer_setup_ops *setup_ops,
-       const struct attribute **buffer_attrs)
+       const struct iio_dev_attr **buffer_attrs)
 {
        struct iio_buffer *buffer;
        int ret;
@@ -110,7 +110,7 @@ int devm_iio_triggered_buffer_setup_ext(struct device *dev,
                                        irqreturn_t (*thread)(int irq, void *p),
                                        enum iio_buffer_direction direction,
                                        const struct iio_buffer_setup_ops *ops,
-                                       const struct attribute **buffer_attrs)
+                                       const struct iio_dev_attr **buffer_attrs)
 {
        int ret;
 
index 35d8b4077376c040bb605df9ddd06e837f8dfe91..05b285f0eb2258b1ffd052ddadbce67e70df4651 100644 (file)
@@ -270,7 +270,7 @@ static struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev)
 int devm_iio_kfifo_buffer_setup_ext(struct device *dev,
                                    struct iio_dev *indio_dev,
                                    const struct iio_buffer_setup_ops *setup_ops,
-                                   const struct attribute **buffer_attrs)
+                                   const struct iio_dev_attr **buffer_attrs)
 {
        struct iio_buffer *buffer;
 
index 05a28d353e343b03d2b9785f2f517bc6a4270f5c..943e9e14d1e99259d87b2daefcd5d56be12bc700 100644 (file)
@@ -172,9 +172,9 @@ static ssize_t hwfifo_watermark_max_show(struct device *dev,
 
 static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
 
-static const struct attribute *cros_ec_sensor_fifo_attributes[] = {
-       &iio_dev_attr_hwfifo_timeout.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
+static const struct iio_dev_attr *cros_ec_sensor_fifo_attributes[] = {
+       &iio_dev_attr_hwfifo_timeout,
+       &iio_dev_attr_hwfifo_watermark_max,
        NULL,
 };
 
index 1151434038d40f16e25ab86bfa607dcf291228d6..ad8910e6ad59df1e7c306efc72586fd285670363 100644 (file)
@@ -75,9 +75,9 @@ static IIO_DEVICE_ATTR(hwfifo_timeout, 0644,
 static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
                       _hid_sensor_get_fifo_state, NULL, 0);
 
-static const struct attribute *hid_sensor_fifo_attributes[] = {
-       &iio_dev_attr_hwfifo_timeout.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+static const struct iio_dev_attr *hid_sensor_fifo_attributes[] = {
+       &iio_dev_attr_hwfifo_timeout,
+       &iio_dev_attr_hwfifo_enabled,
        NULL,
 };
 
@@ -231,7 +231,7 @@ static const struct iio_trigger_ops hid_sensor_trigger_ops = {
 int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
                                struct hid_sensor_common *attrb)
 {
-       const struct attribute **fifo_attrs;
+       const struct iio_dev_attr **fifo_attrs;
        int ret;
        struct iio_trigger *trig;
 
index 9cd7db549fcbcfeace1911a91ef29d78c71da99b..80c78bd6bbef4970fe39149bddd06b361ad9c74c 100644 (file)
@@ -1605,6 +1605,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
 {
        struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
        struct iio_dev_attr *p;
+       const struct iio_dev_attr *id_attr;
        struct attribute **attr;
        int ret, i, attrn, scan_el_attrcount, buffer_attrcount;
        const struct iio_chan_spec *channels;
@@ -1614,6 +1615,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
                while (buffer->attrs[buffer_attrcount] != NULL)
                        buffer_attrcount++;
        }
+       buffer_attrcount += ARRAY_SIZE(iio_buffer_attrs);
 
        scan_el_attrcount = 0;
        INIT_LIST_HEAD(&buffer->buffer_attr_list);
@@ -1656,7 +1658,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
                }
        }
 
-       attrn = buffer_attrcount + scan_el_attrcount + ARRAY_SIZE(iio_buffer_attrs);
+       attrn = buffer_attrcount + scan_el_attrcount;
        attr = kcalloc(attrn + 1, sizeof(*attr), GFP_KERNEL);
        if (!attr) {
                ret = -ENOMEM;
@@ -1671,10 +1673,11 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
                attr[2] = &dev_attr_watermark_ro.attr;
 
        if (buffer->attrs)
-               memcpy(&attr[ARRAY_SIZE(iio_buffer_attrs)], buffer->attrs,
-                      sizeof(struct attribute *) * buffer_attrcount);
+               for (i = 0, id_attr = buffer->attrs[i];
+                    (id_attr = buffer->attrs[i]); i++)
+                       attr[ARRAY_SIZE(iio_buffer_attrs) + i] =
+                               (struct attribute *)&id_attr->dev_attr.attr;
 
-       buffer_attrcount += ARRAY_SIZE(iio_buffer_attrs);
        buffer->buffer_group.attrs = attr;
 
        for (i = 0; i < buffer_attrcount; i++) {
index e2ca8ea23e191c98ef40c8a191ce0677dfbd446e..89c3fd7c29cafc99a20165fe9c24a27d4c831581 100644 (file)
@@ -123,7 +123,7 @@ struct iio_buffer {
        struct attribute_group buffer_group;
 
        /* @attrs: Standard attributes of the buffer. */
-       const struct attribute **attrs;
+       const struct iio_dev_attr **attrs;
 
        /* @demux_bounce: Buffer for doing gather from incoming scan. */
        void *demux_bounce;
index 8a83fb58232d5f40c750cfe4aa9c217788d4dd6a..22874da0c8be96ea8f29784499568fa423159314 100644 (file)
@@ -5,6 +5,7 @@
 struct iio_buffer;
 struct iio_buffer_setup_ops;
 struct iio_dev;
+struct iio_dev_attr;
 struct device;
 
 struct iio_buffer *iio_kfifo_allocate(void);
@@ -13,7 +14,7 @@ void iio_kfifo_free(struct iio_buffer *r);
 int devm_iio_kfifo_buffer_setup_ext(struct device *dev,
                                    struct iio_dev *indio_dev,
                                    const struct iio_buffer_setup_ops *setup_ops,
-                                   const struct attribute **buffer_attrs);
+                                   const struct iio_dev_attr **buffer_attrs);
 
 #define devm_iio_kfifo_buffer_setup(dev, indio_dev, setup_ops) \
        devm_iio_kfifo_buffer_setup_ext((dev), (indio_dev), (setup_ops), NULL)
index 7490b05fc5b2f5f05ad862be02a67107142b9174..29e1fe146879a1abf77387780db723576dacdc69 100644 (file)
@@ -5,8 +5,8 @@
 #include <linux/iio/buffer.h>
 #include <linux/interrupt.h>
 
-struct attribute;
 struct iio_dev;
+struct iio_dev_attr;
 struct iio_buffer_setup_ops;
 
 int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev,
@@ -14,7 +14,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev,
        irqreturn_t (*thread)(int irq, void *p),
        enum iio_buffer_direction direction,
        const struct iio_buffer_setup_ops *setup_ops,
-       const struct attribute **buffer_attrs);
+       const struct iio_dev_attr **buffer_attrs);
 void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev);
 
 #define iio_triggered_buffer_setup(indio_dev, h, thread, setup_ops)            \
@@ -28,7 +28,7 @@ int devm_iio_triggered_buffer_setup_ext(struct device *dev,
                                        irqreturn_t (*thread)(int irq, void *p),
                                        enum iio_buffer_direction direction,
                                        const struct iio_buffer_setup_ops *ops,
-                                       const struct attribute **buffer_attrs);
+                                       const struct iio_dev_attr **buffer_attrs);
 
 #define devm_iio_triggered_buffer_setup(dev, indio_dev, h, thread, setup_ops)  \
        devm_iio_triggered_buffer_setup_ext((dev), (indio_dev), (h), (thread),  \