[PATCH v4 9/9] pseries/plpks/wrapkey: expose PKWM wrapping key management to userspace via sysfs
sashiko-bot at kernel.org
sashiko-bot at kernel.org
Sat Oct 17 18:51:50 UTC 2026
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] powerpc/pseries/plpks: use-after-free of plpks_kobj in plpks_init_child_kobj()
- [Medium] powerpc/pseries: wrapkey_sysfs_init() does not ensure default key exists
--
commit 81ec5557b710c94f51afed01c64f4716ffcf0140
Author: Srish Srinivasan <ssrish at linux.ibm.com>
pseries/plpks/wrapkey: expose PKWM wrapping key management to userspace via sysfs
This commit adds a sysfs interface under /sys/firmware/plpks/wrapkey to allow
userspace to create, revoke, unrevoke, delete, and list PKWM wrapping keys by
label.
> diff --git a/Documentation/ABI/testing/sysfs-firmware-plpks b/Documentation/ABI/testing/sysfs-firmware-plpks
> index cba061e4eee2a..4144e868da1b1 100644
> --- a/Documentation/ABI/testing/sysfs-firmware-plpks
> +++ b/Documentation/ABI/testing/sysfs-firmware-plpks
[ ... ]
> +What: /sys/firmware/plpks/wrapkey/list_active
> +Date: August 2026
> +Contact: Srish Srinivasan <ssrish at linux.ibm.com>
> +Description: (RO) List the labels of active, non-revoked wrapping keys. The
> + default wrapping key, named "default-wrapping-key", is always
> + included in this list.
> +
> + For example:
> +
> + cat /sys/firmware/plpks/wrapkey/list_active
[ ... ]
> diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
> index 7d125e288f6ef..14d2eed4d881a 100644
> --- a/arch/powerpc/platforms/pseries/Kconfig
> +++ b/arch/powerpc/platforms/pseries/Kconfig
> @@ -215,3 +215,18 @@ config PPC_SVM
> those guests.
>
> If unsure, say "N".
> +
> +config PLPKS_WRAPKEY_SYSFS
> + bool "Enable sysfs interface for managing PKWM wrapping keys"
> + default n
> + depends on PSERIES_PLPKS
> + depends on SYSFS
> + depends on TRUSTED_KEYS_PKWM
> + help
> + The PKWM trusted source supports user-created wrapping keys that are
> + managed by the OS. These wrapping keys can be created, revoked,
> + unrevoked, and deleted through sysfs. Their labels can also be viewed
> + through sysfs.
> +
> + Say Y if PLPKS and PKWM are enabled and you want to isolate trusted
> + keys using user-created wrapping keys.
[ ... ]
> diff --git a/arch/powerpc/platforms/pseries/plpks-sysfs.c b/arch/powerpc/platforms/pseries/plpks-sysfs.c
> index f2436229f3233..0ca13bb6405f8 100644
> --- a/arch/powerpc/platforms/pseries/plpks-sysfs.c
> +++ b/arch/powerpc/platforms/pseries/plpks-sysfs.c
> @@ -55,6 +55,17 @@ static umode_t plpks_config_attr_is_visible(struct kobject *kobj,
> return attr->mode;
> }
>
> +int plpks_init_child_kobj(struct kobject *kobj, const struct kobj_type *ktype,
> + const char *name)
> +{
> + kobject_init(kobj, ktype);
> +
> + if (!plpks_kobj)
> + return -ENODEV;
> +
> + return kobject_add(kobj, plpks_kobj, "%s", name);
> +}
> +
> int plpks_config_create_softlink(struct kobject *from)
> {
> if (!plpks_config_kobj)
[Severity: Medium]
Can plpks_init_child_kobj() dereference a freed plpks_kobj if
plpks_sysfs_init() fails after creating plpks_kobj?
In arch/powerpc/platforms/pseries/plpks-sysfs.c:plpks_sysfs_init():
plpks_config_kobj = kobject_create_and_add("config", plpks_kobj);
if (!plpks_config_kobj) {
pr_err("Failed to create plpks config kobj\n");
kobject_put(plpks_kobj);
return -ENOMEM;
}
rc = plpks_sysfs_config(plpks_config_kobj);
if (rc) {
pr_err("Failed to create attribute group for plpks config\n");
kobject_put(plpks_config_kobj);
kobject_put(plpks_kobj);
return rc;
}
If either of those steps fails during machine_subsys_initcall, kobject_put()
frees plpks_kobj without resetting the static pointer to NULL. When
wrapkey_sysfs_init() later runs at machine_late_initcall and calls
plpks_init_child_kobj(), the !plpks_kobj check passes and kobject_add()
operates on the dangling plpks_kobj pointer.
> diff --git a/arch/powerpc/platforms/pseries/plpks-wrapkey-sysfs.c b/arch/powerpc/platforms/pseries/plpks-wrapkey-sysfs.c
> new file mode 100644
> index 0000000000000..d810d6d64fb92
> --- /dev/null
> +++ b/arch/powerpc/platforms/pseries/plpks-wrapkey-sysfs.c
[ ... ]
> +static __init int wrapkey_sysfs_init(void)
> +{
> + int rc;
> +
> + if (!plpks_revoke_is_supported()) {
> + pr_err("H_PKS_{UN}REVOKE_OBJECT interface not supported\n");
> + return -ENODEV;
> + }
> +
> + wrapkey_kobj = kzalloc_obj(*wrapkey_kobj);
> + if (!wrapkey_kobj)
> + return -ENOMEM;
> +
> + rc = plpks_init_child_kobj(wrapkey_kobj, &wrapkey_ktype, "wrapkey");
> +
> + if (rc) {
> + kobject_put(wrapkey_kobj);
> + wrapkey_kobj = NULL;
> + }
> +
> + return rc;
> +}
> +
> +machine_late_initcall(pseries, wrapkey_sysfs_init);
[Severity: Medium]
Is "default-wrapping-key" guaranteed to exist in PLPKS when
wrapkey_sysfs_init() exposes /sys/firmware/plpks/wrapkey?
Both the commit message and Documentation/ABI/testing/sysfs-firmware-plpks
state that "default-wrapping-key" is always included in list_active, and
create_store() rejects "default-wrapping-key" with -EEXIST.
However, "default-wrapping-key" is only generated in
security/keys/trusted-keys/trusted_pkwm.c:trusted_pkwm_init():
var = (struct plpks_var) {
.name = (u8 *)PLPKS_DEFAULT_WRAPKEY_LABEL,
.namelen = sizeof(PLPKS_DEFAULT_WRAPKEY_LABEL) - 1,
.policy = PLPKS_WRAPPINGKEY,
.os = PLPKS_VAR_LINUX,
.component = PLPKS_WRAPKEY_COMPONENT
};
ret = plpks_gen_wrapping_key(&var);
Because CONFIG_PLPKS_WRAPKEY_SYSFS is a bool while CONFIG_TRUSTED_KEYS is
tristate, wrapkey_sysfs_init() runs at machine_late_initcall even when
trusted.ko has not been loaded, or when init_trusted() selects another
trusted key source (such as TPM) earlier in trusted_key_sources[]. On a fresh
LPAR where trusted_pkwm_init() has not run, won't reading list_active omit
"default-wrapping-key" while writing "default-wrapping-key" to create fails
with -EEXIST?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261017183853.596052-1-ssrish@linux.ibm.com?part=9
More information about the Linux-security-module-archive
mailing list