diff mbox series

[v2,02/10] pseries/plpks: fix error handling in plpks_read_var()

Message ID 20260831111738.334857-3-ssrish@linux.ibm.com (mailing list archive)
State New
Headers show
Series Extend PKWM to support user-created wrapping keys | expand

Commit Message

Srish Srinivasan Aug. 31, 2026, 11:17 a.m. UTC
When a plpks variable is initialized without a policy and used to read an
object with the 'wrapping key' policy set, the hypervisor returns
H_AUTHORITY along with the object's policy. However, plpks_read_var() at
present treats this the same as any other H_AUTHORITY failure and returns
an error without propagating the policy information to the caller.

Distinguish this case from other H_AUTHORITY failures and only propagate
policy information when it is returned alongside H_AUTHORITY by the
hypervisor. Remove the explicit assignment of rc to zero in the case of
H_SUCCESS as it is redundant.

Also return -EPERM instead of -EINVAL when the 'wrapping key' policy bit is
set by the caller, better reflecting the access restriction being enforced.

Fixes: 2454a7af0f2a ("powerpc/pseries: define driver for Platform KeyStore")
Fixes: 133aa79e211d ("pseries/plpks: add HCALLs for PowerVM Key Wrapping Module")
Cc: stable@vger.kernel.org
Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
---
 arch/powerpc/platforms/pseries/plpks.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

Comments

R Nageswara Sastry Sept. 4, 2026, 6:10 a.m. UTC | #1
On 31.08.2026 4:47 PM, Srish Srinivasan wrote:
> When a plpks variable is initialized without a policy and used to read an
> object with the 'wrapping key' policy set, the hypervisor returns
> H_AUTHORITY along with the object's policy. However, plpks_read_var() at
> present treats this the same as any other H_AUTHORITY failure and returns
> an error without propagating the policy information to the caller.
>
> Distinguish this case from other H_AUTHORITY failures and only propagate
> policy information when it is returned alongside H_AUTHORITY by the
> hypervisor. Remove the explicit assignment of rc to zero in the case of
> H_SUCCESS as it is redundant.
>
> Also return -EPERM instead of -EINVAL when the 'wrapping key' policy bit is
> set by the caller, better reflecting the access restriction being enforced.
>
> Fixes: 2454a7af0f2a ("powerpc/pseries: define driver for Platform KeyStore")
> Fixes: 133aa79e211d ("pseries/plpks: add HCALLs for PowerVM Key Wrapping Module")
> Cc: stable@vger.kernel.org
> Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>

Tested on ppc64le PowerVM LPARs on firmware with wrap/unwrap support,
with and without Secure Boot enabled.

Verified that PKWM initialisation succeeds and the trusted key seal/unseal
round-trip works correctly. Confirmed that -EPERM is now returned (instead
of -EINVAL) when a read is attempted on an object with the wrapping key
policy bit set. The full key lifecycle (create, export, reload) passed on
all configurations.
> ---
>   arch/powerpc/platforms/pseries/plpks.c | 13 ++++++-------
>   1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c
> index 23e4e2a922fc..7bd5c149dd09 100644
> --- a/arch/powerpc/platforms/pseries/plpks.c
> +++ b/arch/powerpc/platforms/pseries/plpks.c
> @@ -826,7 +826,7 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
>   		return -EINVAL;
>   
>   	if (var->policy & PLPKS_WRAPPINGKEY)
> -		return -EINVAL;
> +		return -EPERM;
>   
>   	auth = construct_auth(consumer);
>   	if (IS_ERR(auth))
> @@ -856,22 +856,21 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
>   				 virt_to_phys(var->name), var->namelen, virt_to_phys(output),
>   				 maxobjsize);
>   
> -
>   	if (rc != H_SUCCESS) {
>   		rc = pseries_status_to_err(rc);
> -		goto out_free_output;
> +		if (rc != -EPERM || !retbuf[1])
> +			goto out_free_output;
> +		goto out_copy_policy;
>   	}
>   
>   	if (!var->data || var->datalen > retbuf[0])
>   		var->datalen = retbuf[0];
>   
> -	var->policy = retbuf[1];
> -
>   	if (var->data)
>   		memcpy(var->data, output, var->datalen);
>   
> -	rc = 0;
> -
> +out_copy_policy:
> +	var->policy = retbuf[1];
>   out_free_output:
>   	kfree(output);
>   out_free_label:
diff mbox series

Patch

diff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c
index 23e4e2a922fc..7bd5c149dd09 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -826,7 +826,7 @@  static int plpks_read_var(u8 consumer, struct plpks_var *var)
 		return -EINVAL;
 
 	if (var->policy & PLPKS_WRAPPINGKEY)
-		return -EINVAL;
+		return -EPERM;
 
 	auth = construct_auth(consumer);
 	if (IS_ERR(auth))
@@ -856,22 +856,21 @@  static int plpks_read_var(u8 consumer, struct plpks_var *var)
 				 virt_to_phys(var->name), var->namelen, virt_to_phys(output),
 				 maxobjsize);
 
-
 	if (rc != H_SUCCESS) {
 		rc = pseries_status_to_err(rc);
-		goto out_free_output;
+		if (rc != -EPERM || !retbuf[1])
+			goto out_free_output;
+		goto out_copy_policy;
 	}
 
 	if (!var->data || var->datalen > retbuf[0])
 		var->datalen = retbuf[0];
 
-	var->policy = retbuf[1];
-
 	if (var->data)
 		memcpy(var->data, output, var->datalen);
 
-	rc = 0;
-
+out_copy_policy:
+	var->policy = retbuf[1];
 out_free_output:
 	kfree(output);
 out_free_label: