From: Matt Fleming <[email protected]>

commit fb7a84cac03541f4da18dfa25b3f4767d4efc6fc upstream.

Dan Carpenter reports that passing the address of the pointer to the
kmalloc()'d memory for 'capsule' is dangerous:

 "drivers/firmware/efi/capsule.c:109 efi_capsule_supported()
  warn: did you mean to pass the address of 'capsule'

   108
   109          status = efi.query_capsule_caps(&capsule, 1, &max_size, reset);
                                                ^^^^^^^^
  If we modify capsule inside this function call then at the end of the
  function we aren't freeing the original pointer that we allocated."

Ard Biesheuvel noted that we don't even need to call kmalloc() since the
object we allocate isn't very big and doesn't need to persist after the
function returns.

Place 'capsule' on the stack instead.

Suggested-by: Ard Biesheuvel <[email protected]>
Reported-by: Dan Carpenter <[email protected]>
Signed-off-by: Matt Fleming <[email protected]>
Acked-by: Ard Biesheuvel <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: Bryan O'Donoghue <[email protected]>
Cc: Denys Vlasenko <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Kweh Hock Leong <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: joeyli <[email protected]>
Cc: [email protected]
Link: 
http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
 drivers/firmware/efi/capsule.c | 29 +++++++++++------------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c
index 0de55944ac0b..61e51249ef40 100644
--- a/drivers/firmware/efi/capsule.c
+++ b/drivers/firmware/efi/capsule.c
@@ -90,33 +90,26 @@ out:
  */
 int efi_capsule_supported(efi_guid_t guid, u32 flags, size_t size, int *reset)
 {
-       efi_capsule_header_t *capsule;
+       efi_capsule_header_t capsule;
+       efi_capsule_header_t *cap_list[] = { &capsule };
        efi_status_t status;
        u64 max_size;
-       int rv = 0;
 
        if (flags & ~EFI_CAPSULE_SUPPORTED_FLAG_MASK)
                return -EINVAL;
 
-       capsule = kmalloc(sizeof(*capsule), GFP_KERNEL);
-       if (!capsule)
-               return -ENOMEM;
-
-       capsule->headersize = capsule->imagesize = sizeof(*capsule);
-       memcpy(&capsule->guid, &guid, sizeof(efi_guid_t));
-       capsule->flags = flags;
+       capsule.headersize = capsule.imagesize = sizeof(capsule);
+       memcpy(&capsule.guid, &guid, sizeof(efi_guid_t));
+       capsule.flags = flags;
 
-       status = efi.query_capsule_caps(&capsule, 1, &max_size, reset);
-       if (status != EFI_SUCCESS) {
-               rv = efi_status_to_err(status);
-               goto out;
-       }
+       status = efi.query_capsule_caps(cap_list, 1, &max_size, reset);
+       if (status != EFI_SUCCESS)
+               return efi_status_to_err(status);
 
        if (size > max_size)
-               rv = -ENOSPC;
-out:
-       kfree(capsule);
-       return rv;
+               return -ENOSPC;
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(efi_capsule_supported);
 
-- 
2.12.3

--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to