Update plpks_wrap_object() and plpks_unwrap_object() to use u64 length
parameters, matching the underlying hcall data types for consistency.
Update the PKWM consumer, where these interfaces are used, accordingly.

Add explicit casts when copying values from hcall return buffers into
narrower data types. This makes the intended conversion clear and avoids
implicit truncation in PLPKS hcall result handling.

Also validate input pointers in plpks_signed_update_var() and
plpks_read_var() before dereferencing them, addressing missing validation
when reading and updating PLPKS objects.

Fixes: 133aa79e211d ("pseries/plpks: add HCALLs for PowerVM Key Wrapping 
Module")
Fixes: 2454a7af0f2a ("powerpc/pseries: define driver for Platform KeyStore")
Fixes: 899d9b8fee66 ("powerpc/pseries: Implement signed update for PLPKS 
objects")
Fixes: c99fcb0d735b ("keys/trusted_keys: establish PKWM as a trusted source")
Signed-off-by: Srish Srinivasan <[email protected]>
---
 arch/powerpc/include/asm/plpks.h          |  8 ++++----
 arch/powerpc/platforms/pseries/plpks.c    | 22 ++++++++++++++--------
 security/keys/trusted-keys/trusted_pkwm.c |  4 ++--
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
index e87f90e40d4e..8b2ffb27db5a 100644
--- a/arch/powerpc/include/asm/plpks.h
+++ b/arch/powerpc/include/asm/plpks.h
@@ -118,11 +118,11 @@ bool plpks_wrapping_is_supported(void);
 
 int plpks_gen_wrapping_key(void);
 
-int plpks_wrap_object(u8 **input_buf, u32 input_len, u16 wrap_flags,
-                     u8 **output_buf, u32 *output_len);
+int plpks_wrap_object(u8 **input_buf, u64 input_len, u16 wrap_flags,
+                     u8 **output_buf, u64 *output_len);
 
-int plpks_unwrap_object(u8 **input_buf, u32 input_len,
-                       u8 **output_buf, u32 *output_len);
+int plpks_unwrap_object(u8 **input_buf, u64 input_len,
+                       u8 **output_buf, u64 *output_len);
 #else // CONFIG_PSERIES_PLPKS
 static inline bool plpks_is_available(void) { return false; }
 static inline u16 plpks_get_passwordlen(void) { BUILD_BUG(); }
diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index 7bd5c149dd09..45278c5a45c1 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -576,7 +576,7 @@ static int plpks_confirm_object_flushed(struct label *label,
                                 virt_to_phys(auth), virt_to_phys(label),
                                 label->size);
 
-               status = retbuf[0];
+               status = (u8)retbuf[0];
                if (rc) {
                        timed_out = false;
                        if (rc == H_NOT_FOUND && status == 1)
@@ -637,6 +637,9 @@ int plpks_signed_update_var(struct plpks_var *var, u64 
flags)
        u64 continuetoken = 0;
        u64 timeout = 0;
 
+       if (!var)
+               return -EINVAL;
+
        if (!var->data || var->datalen <= 0 || var->namelen > 
PLPKS_MAX_NAME_SIZE)
                return -EINVAL;
 
@@ -822,6 +825,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;
 
@@ -863,14 +869,14 @@ static int plpks_read_var(u8 consumer, struct plpks_var 
*var)
                goto out_copy_policy;
        }
 
-       if (!var->data || var->datalen > retbuf[0])
-               var->datalen = retbuf[0];
+       if (!var->data || var->datalen > (u16)retbuf[0])
+               var->datalen = (u16)retbuf[0];
 
        if (var->data)
                memcpy(var->data, output, var->datalen);
 
 out_copy_policy:
-       var->policy = retbuf[1];
+       var->policy = (u32)retbuf[1];
 out_free_output:
        kfree(output);
 out_free_label:
@@ -1015,8 +1021,8 @@ EXPORT_SYMBOL_GPL(plpks_gen_wrapping_key);
  *
  * Returns: On success 0 is returned, a negative errno if not.
  */
-int plpks_wrap_object(u8 **input_buf, u32 input_len, u16 wrap_flags,
-                     u8 **output_buf, u32 *output_len)
+int plpks_wrap_object(u8 **input_buf, u64 input_len, u16 wrap_flags,
+                     u8 **output_buf, u64 *output_len)
 {
        unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 };
        struct plpks_auth *auth;
@@ -1134,8 +1140,8 @@ EXPORT_SYMBOL_GPL(plpks_wrap_object);
  *
  * Returns: On success 0 is returned, a negative errno if not.
  */
-int plpks_unwrap_object(u8 **input_buf, u32 input_len, u8 **output_buf,
-                       u32 *output_len)
+int plpks_unwrap_object(u8 **input_buf, u64 input_len, u8 **output_buf,
+                       u64 *output_len)
 {
        unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 };
        struct plpks_auth *auth;
diff --git a/security/keys/trusted-keys/trusted_pkwm.c 
b/security/keys/trusted-keys/trusted_pkwm.c
index bf42c6679245..b6b5697426a8 100644
--- a/security/keys/trusted-keys/trusted_pkwm.c
+++ b/security/keys/trusted-keys/trusted_pkwm.c
@@ -83,7 +83,7 @@ static int trusted_pkwm_seal(struct trusted_key_payload *p, 
char *datablob)
        struct trusted_key_options *options = NULL;
        struct trusted_pkwm_options *pkwm = NULL;
        u8 *input_buf, *output_buf;
-       u32 output_len, input_len;
+       u64 output_len, input_len;
        int rc;
 
        options = trusted_options_alloc();
@@ -130,7 +130,7 @@ static int trusted_pkwm_seal(struct trusted_key_payload *p, 
char *datablob)
 static int trusted_pkwm_unseal(struct trusted_key_payload *p, char *datablob)
 {
        u8 *input_buf, *output_buf;
-       u32 input_len, output_len;
+       u64 input_len, output_len;
        int rc;
 
        input_len = p->blob_len;
-- 
2.52.0


Reply via email to