All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Denis Benato" <denis.benato@linux.dev>
Cc: dmitry.torokhov@gmail.com, linux-input@vger.kernel.org
Subject: Re: [PATCH 12/12] HID: asus: add support for btn remapping
Date: Thu, 13 Aug 2026 15:12:55 +0000	[thread overview]
Message-ID: <20260813151256.1BCCC1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260813144736.2477941-13-denis.benato@linux.dev>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Use-After-Free (UAF) in sysfs store functions due to manual lockless deallocation of button mappings.
- [High] Sysfs attributes are exposed before `gamepad_mode` initialization, causing a reproducible NULL pointer dereference.
- [Medium] Hardware update errors are silently swallowed for non-Ally X devices, and the software cache is permanently corrupted on failure.
- [Medium] Button remapping sysfs attributes are entirely inaccessible for devices lacking turbo support.
- [Medium] Time-of-Check to Time-of-Use (TOCTOU) race condition in `button_remap_store` bypasses validation.
--

--- Patch [12]: [PATCH 12/12] HID: asus: add support for btn remapping ---
commit d94c33db2e53bcd63e5e7044bbdf330bf4916ffa
Author: Denis Benato <denis.benato@linux.dev>
Subject: HID: asus: add support for btn remapping

Add support for buttons remapping: the ability to assign different
button events to each one of the physical button on the device.

[ ... ]

> diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
> index 359832395afec..5b744dba98d3e 100644
> --- a/drivers/hid/hid-asus.c
> +++ b/drivers/hid/hid-asus.c

[ ... ]

> @@ -2528,29 +3311,78 @@ static struct ally_btn_turbo_attr *ally_btn_turbo_attr_create(struct hid_device
> +static ssize_t button_remap_show(struct device *dev,
> +				 struct device_attribute *attr, char *buf)
> +{
> +	struct hid_device *hdev = to_hid_device(dev);
> +	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
> +	struct ally_handheld *ally = drvdata->rog_ally;
> +	struct button_remap_attr *btn_attr = to_button_remap_attr(attr);
> +	struct ally_config *cfg;
> +	enum ally_button_id button_id = btn_attr->button_id;
> +	enum btn_pair_index pair_idx;
> +	bool is_first;
> +	struct button_pair_map *pair;
> +	struct button_map *btn_map;
> +	int ret;
> +
> +	if (!ally || !ally->config)
> +		return -ENODEV;
> +
> +	cfg = ally->config;
> +
> +	ret = get_button_pair_info(button_id, &pair_idx, &is_first);
> +	if (ret < 0)
> +		return ret;
> +
> +	guard(mutex)(&cfg->config_mutex);
> +	pair = &((struct ally_button_mapping
> +			  *)(cfg->button_mappings))[cfg->gamepad_mode]
> +			.button_pairs[pair_idx - 1];
> +	btn_map = is_first ? &pair->first : &pair->second;
> +
> +	if (btn_attr->is_macro) {
> +		if (btn_map->macro->type == BTN_TYPE_NONE)

[Severity: High]
Could btn_map->macro be NULL here during device initialization?

When ally_create_button_attributes() registers the sysfs groups,
cfg->gamepad_mode is 0 by default. It is not set to 1 (Gamepad) until later
in the probe sequence.

If a user reads the remap or macro sysfs files before cfg->gamepad_mode is
updated, this will index cfg->button_mappings[0]. Since only indexes 1 and 2
are populated by ally_set_default_gamepad_mapping() and
ally_set_default_keyboard_mapping(), the pointers in index 0 remain
uninitialized. Dereferencing btn_map->macro->type would then cause a kernel
panic.

> +			return sysfs_emit(buf, "NONE\n");
> +		else
> +			return sysfs_emit(buf, "%s\n", btn_map->macro->name);
> +	} else {
> +		if (btn_map->remap->type == BTN_TYPE_NONE)
> +			return sysfs_emit(buf, "NONE\n");
> +		else
> +			return sysfs_emit(buf, "%s\n", btn_map->remap->name);
> +	}
> +}

[ ... ]

> +static ssize_t button_remap_store(struct device *dev,
> +				  struct device_attribute *attr,
> +				  const char *buf, size_t count)
> +{

[ ... ]

> +	ret = get_button_pair_info(button_id, &pair_idx, &is_first);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* Validate that the remap target is allowed for this button/mode */
> +	if (!ally_remap_code_valid(button_id, cfg->gamepad_mode, code))
> +		return -EINVAL;
> +
> +	scoped_guard(mutex, &cfg->config_mutex) {
> +		/* Access the mapping for current gamepad mode */
> +		pair = &((struct ally_button_mapping
> +				  *)(cfg->button_mappings))[cfg->gamepad_mode]

[Severity: Medium]
Is there a Time-of-Check to Time-of-Use (TOCTOU) race condition here?

The validation function ally_remap_code_valid() reads cfg->gamepad_mode
locklessly. If a concurrent sysfs write to gamepad_mode_store() alters the
mode right before cfg->config_mutex is acquired, an invalid mapping could
bypass the checks and be written to the new mode's configuration.

> +				.button_pairs[pair_idx - 1];
> +		btn_map = is_first ? &pair->first : &pair->second;
> +
> +		if (btn_attr->is_macro)
> +			btn_map->macro = (struct btn_code_map *)code;
> +		else
> +			btn_map->remap = (struct btn_code_map *)code;
> +
> +		/* Update pair index */
> +		pair->pair_index = pair_idx;
> +
> +		/*
> +		 * Send mapping to device with the caveat that first generation
> +		 * devices require individual button pair updates.
> +		 */
> +		if (cfg->is_ally_x) {
> +			ret = ally_set_button_mapping(hdev, ally, pair);
> +			if (ret < 0)
> +				return ret;
> +		} else {
> +			mode_map = &((struct ally_button_mapping
> +					 *)(cfg->button_mappings))[cfg->gamepad_mode];
> +			for (i = 0; i < 9; i++) {
> +				mode_map->button_pairs[i].pair_index = i + 1;
> +				ret = ally_set_button_mapping(hdev, ally,
> +					&mode_map->button_pairs[i]);
> +				if (ret < 0)
> +					break;
> +			}
> +		}
> +	}
> +
> +	return count;
> +}

[Severity: Medium]
For non-Ally X devices, if ally_set_button_mapping() fails, this loop breaks
but then unconditionally returns count (success) instead of ret.

Also, earlier in this block, the software cache is updated:

    if (btn_attr->is_macro)
        btn_map->macro = (struct btn_code_map *)code;
    else
        btn_map->remap = (struct btn_code_map *)code;

If the hardware update fails, does this mean the software cache is now
permanently desynchronized from the actual hardware state?

[ ... ]

> @@ -2528,29 +3311,78 @@ static struct ally_btn_turbo_attr *ally_btn_turbo_attr_create(struct hid_device
>  static int ally_create_button_attributes(struct hid_device *hdev, struct ally_config *cfg)
>  {
>  	struct ally_btn_sysfs_entry *entries;
> +	struct ally_button_mapping *mappings;
>  	int i, ret;
>  
> -	if (!cfg->turbo_support)
> -		return 0;
> -

[Severity: Medium]
Even though this check is removed here, does the caller (ally_config_create())
still restrict the creation of these attributes based on cfg->turbo_support?

If ally_create_button_attributes() is only called when cfg->turbo_support is
true, then devices without turbo support will not have access to the button
remapping sysfs attributes either.

>  	entries = devm_kcalloc(&hdev->dev, ALLY_BTN_MAX, sizeof(*entries), GFP_KERNEL);

[ ... ]

> @@ -2598,8 +3439,16 @@ static void ally_remove_button_attributes(struct hid_device *hdev, struct ally_c
>  	for (i = 0; i < ALLY_BTN_MAX; i++) {
>  		sysfs_remove_group(&hdev->dev.kobj, &entries[i].group);
>  		kfree(entries[i].turbo_attr);
> +		kfree(entries[i].remap_attr);
> +		kfree(entries[i].macro_attr);
> +	}
> +
> +	if (cfg->button_mappings) {
> +		devm_kfree(&hdev->dev, cfg->button_mappings);
> +		cfg->button_mappings = NULL;
>  	}

[Severity: High]
Can this cause a use-after-free if sysfs files are accessed concurrently?

The teardown path frees cfg->button_mappings manually using devm_kfree()
without holding cfg->config_mutex.

If a user writes to gamepad_mode_store() or button_remap_store() right as
this is being freed, it could lead to memory corruption or a kernel panic,
as those functions dereference cfg->button_mappings.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260813144736.2477941-1-denis.benato@linux.dev?part=12

      reply	other threads:[~2026-08-13 15:12 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-13 14:47 [PATCH 00/12] HID: asus: add support for ROG Ally handhelds Denis Benato
2026-08-13 14:47 ` [PATCH 01/12] HID: asus: reinitialize the device after exiting a sleep state Denis Benato
2026-08-13 14:55   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 02/12] HID: asus: add support for ROG Ally handhelds Denis Benato
2026-08-13 15:00   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 03/12] HID: asus: add gamepad configuration Denis Benato
2026-08-13 14:59   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 04/12] HID: asus: add vibration strength configuration Denis Benato
2026-08-13 14:56   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 05/12] HID: asus: add joysticks inner and outer range configuration Denis Benato
2026-08-13 15:02   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 06/12] HID: asus: add triggers " Denis Benato
2026-08-13 14:58   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 07/12] HID: asus: add joysticks anti-deadzone configuration Denis Benato
2026-08-13 15:02   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 08/12] HID: asus: add support for response curve Denis Benato
2026-08-13 14:59   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 09/12] HID: asus: add support to force feedback Denis Benato
2026-08-13 15:10   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 10/12] HID: asus: add support for gamepad mode Denis Benato
2026-08-13 15:10   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 11/12] HID: asus: add support for turbo buttons Denis Benato
2026-08-13 15:10   ` sashiko-bot
2026-08-13 14:47 ` [PATCH 12/12] HID: asus: add support for btn remapping Denis Benato
2026-08-13 15:12   ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260813151256.1BCCC1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=denis.benato@linux.dev \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.