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
prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox