lkml.org 
[lkml]   [2021]   [Oct]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH v7 1/2] hwmon: (asus_wmi_ec_sensors) Support B550 Asus WMI.
On 2021-10-15T08:58+0300, Denis Pauk wrote:
> +/*
> + * The next four functions converts to/from BRxx string argument format
> + * The format of the string is as follows:
> + * The string consists of two-byte UTF-16 characters
> + * The value of the very first byte int the string is equal to the total length
> + * of the next string in bytes, thus excluding the first two-byte character
> + * The rest of the string encodes pairs of (bank, index) pairs, where both
> + * values are byte-long (0x00 to 0xFF)
> + * Numbers are encoded as UTF-16 hex values
> + */
> +static void asus_wmi_ec_decode_reply_buffer(const u8 *inp, u8 *out, u32 length)
> +{
> + char buffer[ASUSWMI_MAX_BUF_LEN * 2];
> + const char *pos = buffer;
> + const u8 *data = inp + 2;
> + unsigned int i;
> + u32 len;
> +
> + len = min3((u32)ASUSWMI_MAX_BUF_LEN, (length - 2) / 4, (u32)inp[0] / 4);

This will still access out of bounds memory when length == 0.

> +
> + utf16s_to_utf8s((wchar_t *)data, len * 2, UTF16_LITTLE_ENDIAN, buffer, len * 2);
> +
> + for (i = 0; i < len; i++, pos += 2)
> + out[i] = (hex_to_bin(pos[0]) << 4) + hex_to_bin(pos[1]);
> +}

> +static int asus_wmi_ec_find_sensor_index(const struct asus_wmi_ec_info *ec,
> + enum hwmon_sensor_types type, int channel)
> +{
> + int i;
> +
> + for (i = 0; i < ec->nr_sensors; i++) {
> + if (known_ec_sensors[ec->sensors[i].info_index].type == type) {
> + if (channel == 0)
> + return i;
> +
> + channel--;
> + }
> + }
> + return -EINVAL;
> +}
> +
> +static int asus_wmi_ec_get_cached_value_or_update(int sensor_index,
> + struct asus_wmi_sensors *state,
> + u32 *value)

In both drivers there is function like this where the caller is responsible
for halding the mutex. Maybe the mutex could be handled by the function
directly.

> +{
> + int ret;
> +
> + if (time_after(jiffies, state->ec.last_updated + HZ)) {
> + ret = asus_wmi_ec_block_read(ASUSWMI_METHODID_BREC,
> + state->ec.read_arg,
> + state->ec.read_buffer);
> + if (ret)
> + return ret;
> +
> + asus_wmi_ec_update_ec_sensors(&state->ec);
> + state->ec.last_updated = jiffies;
> + }
> +
> + *value = state->ec.sensors[sensor_index].cached_value;
> + return 0;
> +}

> +static umode_t asus_wmi_ec_hwmon_is_visible(const void *drvdata,
> + enum hwmon_sensor_types type, u32 attr,
> + int channel)
> +{
> + int index;
> + const struct asus_wmi_sensors *sensor_data = drvdata;
> +
> + index = asus_wmi_ec_find_sensor_index(&sensor_data->ec, type, channel);
> +
> + return index == 0xff ? 0 : 0444;

Should this not check for index < 0?

> +}

> +static int asus_wmi_probe(struct wmi_device *wdev, const void *context)
> +{
> + struct asus_wmi_sensors *sensor_data;
> + struct asus_wmi_data *board_sensors;
> + const enum known_ec_sensor *bsi;
> + const struct dmi_system_id *dmi_id;
> + struct device *dev = &wdev->dev;
> +
> + dmi_id = dmi_first_match(asus_wmi_ec_dmi_table);
> + if (!dmi_id)
> + return -ENODEV;
> +
> + board_sensors = dmi_id->driver_data;
> + if (!board_sensors)
> + return -ENODEV;
> +
> + bsi = board_sensors->known_board_sensors;
> +
> + sensor_data = devm_kzalloc(dev, sizeof(struct asus_wmi_sensors),
> + GFP_KERNEL);

sizeof(*sensor_data);

> + if (!sensor_data)
> + return -ENOMEM;
> +
> + mutex_init(&sensor_data->lock);
> +
> + dev_set_drvdata(dev, sensor_data);
> +
> + /* ec init */
> + return asus_wmi_ec_configure_sensor_setup(dev,
> + sensor_data, bsi);
> +}

\
 
 \ /
  Last update: 2021-10-15 18:41    [W:0.111 / U:0.064 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site