When a PLPKS variable is initialized without a policy and used to read an
object with the PLPKS_WRAPPINGKEY policy set, the hypervisor returns
H_AUTHORITY along with the object's policy. However, plpks_read_var()
currently 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 propagate the
returned policy to the caller while preserving the authorization error.
Remove the explicit assignment of zero to rc on H_SUCCESS, as it is
redundant.

Also validate the PLPKS variable pointer before dereferencing it.

Fixes: 2454a7af0f2a ("powerpc/pseries: define driver for Platform KeyStore")
Cc: [email protected] # 6.0
Signed-off-by: Srish Srinivasan <[email protected]>
Tested-by: R Nageswara Sastry <[email protected]>
---
 arch/powerpc/platforms/pseries/plpks.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index 23e4e2a922fc..7e56b3dcacbc 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -822,6 +822,9 @@ static int plpks_read_var(u8 consumer, struct plpks_var 
*var)
        u8 *output;
        int rc;
 
+       if (!var)
+               return -EINVAL;
+
        if (var->namelen > PLPKS_MAX_NAME_SIZE)
                return -EINVAL;
 
@@ -856,22 +859,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:
-- 
2.52.0


Reply via email to