All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Atharva Tiwari" <atharvatiwarilinuxdev@gmail.com>
Cc: "Bjorn Helgaas" <bhelgaas@google.com>,
	"Thomas Gleixner" <tglx@kernel.org>,
	"Ingo Molnar" <mingo@redhat.com>,
	"Borislav Petkov" <bp@alien8.de>,
	"Dave Hansen" <dave.hansen@linux.intel.com>,
	x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	"Len Brown" <lenb@kernel.org>,
	"Linus Walleij" <linusw@kernel.org>,
	"Bartosz Golaszewski" <brgl@kernel.org>,
	"Sven Peter" <sven@kernel.org>, "Janne Grunau" <j@jannau.net>,
	"Neal Gompa" <neal@gompa.dev>,
	"Guenter Roeck" <linux@roeck-us.net>,
	"Jonathan Cameron" <jic23@kernel.org>,
	"David Lechner" <dlechner@baylibre.com>,
	"Nuno Sá" <nuno.sa@analog.com>,
	"Andy Shevchenko" <andy@kernel.org>, "Lee Jones" <lee@kernel.org>,
	"Pavel Machek" <pavel@kernel.org>,
	"Griffin Kroah-Hartman" <griffin@kroah.com>,
	"Hans de Goede" <hansg@kernel.org>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Sebastian Reichel" <sre@kernel.org>,
	"Alexandre Belloni" <alexandre.belloni@bootlin.com>,
	"Wim Van Sebroeck" <wim@linux-watchdog.org>,
	"Jarkko Sakkinen" <jarkko@kernel.org>,
	"Mimi Zohar" <zohar@linux.ibm.com>,
	"Roberto Sassu" <roberto.sassu@huawei.com>,
	"Dmitry Kasatkin" <dmitry.kasatkin@gmail.com>,
	"Eric Snowberg" <eric.snowberg@oracle.com>,
	"Paul Moore" <paul@paul-moore.com>,
	"James Morris" <jmorris@namei.org>,
	"Serge E. Hallyn" <serge@hallyn.com>,
	linux-pci@vger.kernel.org, linux-gpio@vger.kernel.org,
	linux-hwmon@vger.kernel.org, linux-leds@vger.kernel.org,
	mfd@lists.linux.dev, linux-rtc@vger.kernel.org,
	linux-watchdog@vger.kernel.org, keyrings@vger.kernel.org,
	linux-security-module@vger.kernel.org
Subject: Re: [RFC PATCH 14/14] mfd/macsmc: add ioctl to access smc keys
Date: Thu, 29 Oct 2026 09:26:19 +0000	[thread overview]
Message-ID: <sashiko-outbox-189036@kernel.org> (raw)
In-Reply-To: <20261029085504.3547-15-atharvatiwarilinuxdev@gmail.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] mfd: macsmc: use-after-free in apple_smc_fops_ioctl() after device unbind
- [Medium] mfd: macsmc: size_t in ioctl payload breaks compat_ioctl in apple_smc_fops
- [Medium] mfd: macsmc: incomplete write blocklist in apple_smc_fops_ioctl()
- [Low] mfd: macsmc: return -ENOTTY for unknown cmd in apple_smc_fops_ioctl()
- [Low] mfd: macsmc: commit subject violates MFD prefix and capitalization rules
--

commit 352ee7db8cfde297319806ac2e104b433cfad104
Author: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>

mfd/macsmc: add ioctl to access smc keys

This commit registers a /dev/smc miscdevice in macsmc-core to allow
userspace to read, write, and query Apple SMC keys via ioctls, while
blocking writes to a static list of keys managed by kernel drivers.

>     mfd/macsmc: add ioctl to access smc keys
>
>     Add a /dev/smc device so userspace can talk to the SMC
>     directly. Some keys that need to be written aren't handled by
>     any driver, or affect several drivers at once, so they
>     can't be exposed cleanly through the kernel interfaces.
>
>     Keys already managed by kernel drivers can't be written this
>     way, to avoid conflicts.
>
>     Signed-off-by: Atharva Tiwari <atharvatiwarilinuxdev@gmail.com>

[Severity: Low]
This isn't a bug, but the MFD subsystem convention uses the prefix format
"mfd: <driver>: <Capitalized description>". Should the commit subject be
formatted as "mfd: macsmc: Add ioctl to access SMC keys"?

> diff --git a/drivers/mfd/macsmc-core.c b/drivers/mfd/macsmc-core.c
> index bc4200f574bd5..a30f7386ef9cd 100644
> --- a/drivers/mfd/macsmc-core.c
> +++ b/drivers/mfd/macsmc-core.c

[ ... ]

> @@ -112,6 +115,144 @@ static void apple_smc_disable_notifications(void *data)
>  	smc->be->disable_notifications(smc->be_cookie);
>  }
>  
> +static long apple_smc_fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> +{
> +	struct apple_smc *smc = file->private_data;
> +	void __user *argp = (void __user *)arg;
> +	int ret;
> +
> +	switch (cmd) {

[ ... ]

> +	case IOCTL_SMC_WRITE: {
> +		struct ioctl_smc_rw_payload payload;
> +		struct apple_smc_key_info info;
> +
> +		if (copy_from_user(&payload, argp, sizeof(payload)))
> +			return -EFAULT;
> +
> +		ret = apple_smc_get_key_info(smc, payload.key, &info);
> +		if (ret < 0)
> +			return ret;
> +
> +		if (payload.size != info.size)
> +			return -EINVAL;
> +
> +		if (payload.size > 32)
> +			return -EINVAL;
> +
> +		switch (payload.key) {
> +		case __SMC_KEY('C', 'H', '0', 'I'):
> +		case __SMC_KEY('C', 'H', '0', 'C'):
> +		case __SMC_KEY('C', 'H', '0', 'K'):
> +		case __SMC_KEY('C', 'H', '0', 'B'):
> +		case __SMC_KEY('C', 'H', 'T', 'E'):
> +		case __SMC_KEY('C', 'H', 'L', 'S'):
> +		case __SMC_KEY('B', 'C', 'L', 'M'):
> +		case __SMC_KEY('M', 'B', 'S', 'E'):
> +		case __SMC_KEY('C', 'L', 'K', 'L'):
> +		case __SMC_KEY('C', 'L', 'K', 'O'):
> +		case __SMC_KEY('O', 'S', 'W', 'D'):
> +		case __SMC_KEY('N', 'A', 'T', 'J'):
> +		case __SMC_KEY('N', 'A', 'T', 'i'):
> +		case __SMC_KEY('N', 'E', 'S', 'N'):
> +		case __SMC_KEY('M', 'O', 'C', 'N'):
> +		case __SMC_KEY('L', 'K', 'S', 'B'):
> +		case __SMC_KEY('N', 'T', 'O', 'K'):
> +		case __SMC_KEY('N', 'T', 'A', 'P'):
> +		case __SMC_KEY('F', '0', 'T', 'g'):
> +		case __SMC_KEY('F', '1', 'T', 'g'):
> +		case __SMC_KEY('F', '0', 'M', 'd'):
> +		case __SMC_KEY('F', '1', 'M', 'd'):
> +		case __SMC_KEY('F', 'S', '!', ' '):
> +			return -EPERM;
> +		}

[Severity: Medium]
Does this static blocklist miss other keys actively managed by MFD child
drivers?

In drivers/hwmon/macsmc-hwmon.c, macsmc_hwmon_create_fan_acpi() registers
all fans up to FNum using keys F<num>Tg and F<num>Md, and
macsmc_hwmon_create_fan() registers fan keys from DT on Apple Silicon:

drivers/hwmon/macsmc-hwmon.c:macsmc_hwmon_create_fan_acpi() {
	const char num_char = num + '0';
	...
	ret = macsmc_hwmon_create_sensor_acpi(smc, &fan->set,
			__SMC_KEY('F', num_char, 'T', 'g'), NULL, 0);
	if (ret)
		return ret;

	if (apple_smc_key_exists(smc, __SMC_KEY('F', num_char, 'M', 'd'))) {
		ret = macsmc_hwmon_create_sensor_acpi(smc, &fan->mode,
				__SMC_KEY('F', num_char, 'M', 'd'), NULL, 0);
}

On systems with more than two fans, fans 2 and above remain writable via
IOCTL_SMC_WRITE, which bypasses the min/max RPM validation in
macsmc_hwmon_write_fan() and desynchronizes hwmon->fan.fans[channel].manual.

Similarly, drivers/gpio/gpio-macsmc.c (registered as macsmc-gpio) manages
and writes PMU GPIO keys gP00..gPff in macsmc_gpio_set():

drivers/gpio/gpio-macsmc.c:macsmc_gpio_set() {
	struct macsmc_gpio *smcgp = gpiochip_get_data(gc);
	smc_key key = macsmc_gpio_key(offset);
	int ret;

	value |= CMD_OUTPUT;
	ret = apple_smc_write_u32(smcgp->smc, key, CMD_OUTPUT | value);
}

None of the gPxx keys are filtered here either, allowing userspace to
modify GPIO outputs behind the kernel driver's back.

[ ... ]

> +	default:
> +		return -EINVAL;
> +	}
> +}

[Severity: Low]
Should the default case in apple_smc_fops_ioctl() return -ENOTTY instead of
-EINVAL for unrecognized ioctl commands?

> +
> +static int apple_smc_fops_open(struct inode *inode, struct file *file)
> +{
> +	struct miscdevice *misc = file->private_data;
> +
> +	file->private_data = container_of(misc, struct apple_smc, miscdev);
> +	return 0;
> +}
> +
> +static const struct file_operations apple_smc_fops = {
> +	.owner		= THIS_MODULE,
> +	.open		= apple_smc_fops_open,
> +	.unlocked_ioctl	= apple_smc_fops_ioctl,
> +	.compat_ioctl	= compat_ptr_ioctl,
> +	.llseek		= noop_llseek,
> +};
> +
> +static void apple_smc_misc_unregister(void *data)
> +{
> +	misc_deregister(data);
> +}
> +
>  int apple_smc_probe(struct device *dev, const struct apple_smc_backend_ops *ops,
>  		void *cookie, struct blocking_notifier_head *event_handlers, bool is_acpi)
>  {
> @@ -150,6 +291,20 @@ int apple_smc_probe(struct device *dev, const struct apple_smc_backend_ops *ops,
>  	if (ret)
>  		return ret;
>  
> +	smc->miscdev.minor = MISC_DYNAMIC_MINOR;
> +	smc->miscdev.name = "smc";
> +	smc->miscdev.fops = &apple_smc_fops;
> +	smc->miscdev.parent = dev;
> +	smc->miscdev.mode = 0600;
> +
> +	ret = misc_register(&smc->miscdev);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_add_action_or_reset(dev, apple_smc_misc_unregister, &smc->miscdev);
> +	if (ret)
> +		return ret;
> +

[Severity: High]
Can this trigger a use-after-free in apple_smc_fops_ioctl() if the backend
device is unbound (or if a subsequent devm_mfd_add_devices() call in
apple_smc_probe() fails) while /dev/smc is open?

In apple_smc_probe(), smc is allocated via devm_kzalloc(dev, sizeof(*smc),
GFP_KERNEL), and smc->be_cookie is similarly devm-allocated on the backend
device. When /dev/smc is opened, apple_smc_fops_open() stores a raw pointer
to smc in file->private_data, and misc_open() only pins apple_smc_fops.owner
(macsmc-core, not the backend driver).

When the device is unbound or probe fails after misc_register(), devres
runs apple_smc_misc_unregister() -> misc_deregister(&smc->miscdev) and then
frees both smc and smc->be_cookie. Because misc_deregister() does not wait
for in-flight ioctls or revoke already-open file descriptors, any concurrent
or subsequent call to apple_smc_fops_ioctl() on the open file will
dereference freed memory via file->private_data when locking smc->mutex and
invoking smc->be callbacks with smc->be_cookie.

> diff --git a/include/linux/mfd/macsmc.h b/include/linux/mfd/macsmc.h
> index 4b4368b99adb6..29fd7b20ce9c8 100644
> --- a/include/linux/mfd/macsmc.h
> +++ b/include/linux/mfd/macsmc.h

[ ... ]

> @@ -141,8 +144,32 @@ struct apple_smc {
>  
>  	struct mutex mutex;
>  	spinlock_t lock;
> +
> +	struct miscdevice miscdev;
> +};
> +
> +struct ioctl_smc_rw_payload {
> +	smc_key key;
> +	size_t size;
> +	u8 buf[32];
> +};
> +
> +struct ioctl_smc_index_payload {
> +	int index;
> +	smc_key key;
> +};
> +
> +struct ioctl_smc_info_payload {
> +	smc_key key;
> +	struct apple_smc_key_info info;
>  };
>  
> +#define APPLE_SMC_MAGIC 'S'
> +#define IOCTL_SMC_READ           _IOWR(APPLE_SMC_MAGIC, 1, struct ioctl_smc_rw_payload)
> +#define IOCTL_SMC_WRITE          _IOW(APPLE_SMC_MAGIC, 2, struct ioctl_smc_rw_payload)
> +#define IOCTL_SMC_GET_KEY_INDEX  _IOWR(APPLE_SMC_MAGIC, 3, struct ioctl_smc_index_payload)
> +#define IOCTL_SMC_GET_KEY_INFO   _IOWR(APPLE_SMC_MAGIC, 4, struct ioctl_smc_info_payload)

[Severity: Medium]
Does using size_t in struct ioctl_smc_rw_payload break 32-bit compat ioctls
even though apple_smc_fops sets .compat_ioctl = compat_ptr_ioctl?

On 64-bit kernels, size_t is 8 bytes with 8-byte alignment, which adds 4
bytes of padding after key (placing size at offset 8, buf at offset 16, and
making sizeof(struct ioctl_smc_rw_payload) == 48). In 32-bit userspace,
size_t is 4 bytes with 4-byte alignment (placing size at offset 4, buf at
offset 8, and making sizeof(struct ioctl_smc_rw_payload) == 40). Because
IOCTL_SMC_READ and IOCTL_SMC_WRITE encode the struct size, 32-bit compat
callers will pass a command number with size 40 that fails to match the
64-bit kernel's command number, or have mismatched field offsets and copy
8 bytes past the userspace struct if invoked with the 64-bit command number.

Also, since these ioctl structs and macros form a userspace ABI, should they
be placed in a header under include/uapi/ using fixed-size UAPI types (__u32,
__u8) with explicit padding rather than in the kernel-internal
include/linux/mfd/macsmc.h header?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261029085504.3547-1-atharvatiwarilinuxdev@gmail.com?part=14

      parent reply	other threads:[~2026-10-29  9:26 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29  8:51 [RFC PATCH 00/14] Add macsmc support for Intel Macs, replacing applesmc Atharva Tiwari
2026-10-29  8:51 ` [RFC PATCH 01/14] treewide: Add backend for macsmc Atharva Tiwari
2026-10-29  9:20   ` sashiko-bot
2026-10-29  8:51 ` [RFC PATCH 02/14] platform/x86: add backend for macsmc in intel macs Atharva Tiwari
2026-10-29  9:23   ` sashiko-bot
2026-10-29 12:59   ` Ilpo Järvinen
2026-10-29  8:52 ` [RFC PATCH 03/14] watchdog: add driver for apple smc Atharva Tiwari
2026-10-29  9:17   ` sashiko-bot
2026-10-29 13:30   ` Andy Shevchenko
2026-10-29  8:52 ` [RFC PATCH 04/14] iio/light: add new driver for macsmc Atharva Tiwari
2026-10-29  9:17   ` sashiko-bot
2026-10-29  8:52 ` [RFC PATCH 05/14] iio/accel: add driver for apple SMS Atharva Tiwari
2026-10-29  9:20   ` sashiko-bot
2026-10-29  8:52 ` [RFC PATCH 06/14] leds: add support for macsmc kbl Atharva Tiwari
2026-10-29  9:16   ` sashiko-bot
2026-10-29  8:52 ` [RFC PATCH 07/14] rtc: add support for x86 macs in macsmc-rtc Atharva Tiwari
2026-10-29  9:15   ` sashiko-bot
2026-10-29  8:52 ` [RFC PATCH 08/14] treewide: Add a flag to detect the Apple T2 chip Atharva Tiwari
2026-10-29  9:11   ` sashiko-bot
2026-10-29  8:52 ` [RFC PATCH 09/14] treewide: disable other rtc's in t2 macs Atharva Tiwari
2026-10-29  9:16   ` sashiko-bot
2026-10-29  8:52 ` [RFC PATCH 10/14] power/supply: add support for x86 macs in macsmc-power Atharva Tiwari
2026-10-29  9:19   ` sashiko-bot
2026-10-29  8:52 ` [RFC PATCH 11/14] acpi: disable battery and adapter for x86 apple machines Atharva Tiwari
2026-10-29  9:13   ` sashiko-bot
2026-10-29  8:52 ` [RFC PATCH 12/14] hwmon/macsmc: add more types Atharva Tiwari
2026-10-29  9:18   ` sashiko-bot
2026-10-29  8:52 ` [RFC PATCH 13/14] hwmon: add support for x86 macs in macsmc-hwmon Atharva Tiwari
2026-10-29  9:20   ` sashiko-bot
2026-10-29  8:52 ` [RFC PATCH 14/14] mfd/macsmc: add ioctl to access smc keys Atharva Tiwari
2026-10-29  9:22   ` Sasha Finkelstein
2026-10-29 14:39     ` Atharva Tiwari
2026-10-29 14:53       ` Sasha Finkelstein
2026-10-29  9:26   ` 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=sashiko-outbox-189036@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=alexandre.belloni@bootlin.com \
    --cc=andy@kernel.org \
    --cc=atharvatiwarilinuxdev@gmail.com \
    --cc=bhelgaas@google.com \
    --cc=bp@alien8.de \
    --cc=brgl@kernel.org \
    --cc=dave.hansen@linux.intel.com \
    --cc=dlechner@baylibre.com \
    --cc=dmitry.kasatkin@gmail.com \
    --cc=eric.snowberg@oracle.com \
    --cc=griffin@kroah.com \
    --cc=hansg@kernel.org \
    --cc=hpa@zytor.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=j@jannau.net \
    --cc=jarkko@kernel.org \
    --cc=jic23@kernel.org \
    --cc=jmorris@namei.org \
    --cc=keyrings@vger.kernel.org \
    --cc=lee@kernel.org \
    --cc=lenb@kernel.org \
    --cc=linusw@kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-rtc@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux-watchdog@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=mfd@lists.linux.dev \
    --cc=mingo@redhat.com \
    --cc=neal@gompa.dev \
    --cc=nuno.sa@analog.com \
    --cc=paul@paul-moore.com \
    --cc=pavel@kernel.org \
    --cc=rafael@kernel.org \
    --cc=roberto.sassu@huawei.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=serge@hallyn.com \
    --cc=sre@kernel.org \
    --cc=sven@kernel.org \
    --cc=tglx@kernel.org \
    --cc=wim@linux-watchdog.org \
    --cc=x86@kernel.org \
    --cc=zohar@linux.ibm.com \
    /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.