public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: Haojian Zhuang <haojian.zhuang@linaro.org>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
	"Leif Lindholm (Linaro address)" <leif.lindholm@linaro.org>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: Re: [PATCH edk2-platforms v5 0/2] add platform boot options
Date: Thu, 26 Apr 2018 12:20:48 +0200	[thread overview]
Message-ID: <32e983cd-ec8e-43bf-4db8-93949a6b0894@redhat.com> (raw)
In-Reply-To: <CAD6h2NStphQr0zWgT3bA+HZvNibLLF-4NgNu0Cwc8yiKHNzYCQ@mail.gmail.com>

On 04/26/18 05:12, Haojian Zhuang wrote:
> On 26 April 2018 at 00:10, Laszlo Ersek <lersek@redhat.com> wrote:

>> (4) In both patches, in both of the CreatePlatformBootOptionFromPath()
>> and CreatePlatformBootOptionFromGuid() helper functions, the
>> "DevicePath" variable is leaked when
>> EfiBootManagerInitializeLoadOption() fails.
>>
>> "DevicePath" should be freed unconditionally at that point, in both
>> patches and in both helper functions (4 instances in total). Simply
>> eliminate the following:
>>
>>   if (EFI_ERROR (Status)) {
>>     return Status;
>>   }
>>
>> and you will be left with:
>>
>>   Status = EfiBootManagerInitializeLoadOption (
>>              ...
>>              );
>>   FreePool (DevicePath);
>>   return Status;
>>
>> I believe I need not separately review this update either.
>>
> 
> For this one, I have a different opinion.
> 
> EFI_STATUS
> EFIAPI
> EfiBootManagerInitializeLoadOption (
>   ...
>   )
> {
>   if ((Option == NULL) || (Description == NULL) || (FilePath == NULL)) {
>     return EFI_INVALID_PARAMETER;
>   }
> 
>   if (((OptionalData != NULL) && (OptionalDataSize == 0)) ||
>       ((OptionalData == NULL) && (OptionalDataSize != 0))) {
>     return EFI_INVALID_PARAMETER;
>   }
>   if ((UINT32) OptionType >= LoadOptionTypeMax) {
>     return EFI_INVALID_PARAMETER;
>   }
> 
>   ZeroMem (Option, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));
>   Option->OptionNumber       = OptionNumber;
>   Option->OptionType         = OptionType;
>   Option->Attributes         = Attributes;
>   Option->Description        = AllocateCopyPool (StrSize
> (Description), Description);
>   Option->FilePath           = DuplicateDevicePath (FilePath);
>   if (OptionalData != NULL) {
>     Option->OptionalData     = AllocateCopyPool (OptionalDataSize,
> OptionalData);
>     Option->OptionalDataSize = OptionalDataSize;
>   }
> 
>   return EFI_SUCCESS;
> }
> 
> We can find that no memory is allocated to "DevicePath" if it returns
> with error.
> 
> So we shouldn't free memory on "DevicePath" if "Status" is error code.

I disagree. We have:

  CreatePlatformBootOptionFromPath()
    DevicePath = ConvertTextToDevicePath(...)              #1
    EfiBootManagerInitializeLoadOption(... DevicePath ...)
      DuplicateDevicePath(FilePath=DevicePath)             #2

The ConvertTextToDevicePath() function returns the binary representation
of the device path in a dynamically allocated area. That is dynamic
object #1, tracked by the "DevicePath" variable. Then,
EfiBootManagerInitializeLoadOption() creates a deep copy, by calling the
DuplicateDevicePath() function. That creates dynamic object #2, tracked
by Option->FilePath.

- If EfiBootManagerInitializeLoadOption() returns with failure, then
dynamic object #2 does not exist, and we no longer need dynamic object
#1, so we have to free dynamic object #1.

- If EfiBootManagerInitializeLoadOption() returns with success, then
dynamic object #2 exists, and is correctly tracked by Option->FilePath.
We no longer need dynamic object #1, so we have to free it.

In other words, regardless of the return status of
EfiBootManagerInitializeLoadOption(), we must release dynamic object #1.
We need dynamic object #1 only temporarily, so we can call
EfiBootManagerInitializeLoadOption(), and let it make a copy.

The same applies to CreatePlatformBootOptionFromGuid(), except replace
ConvertTextToDevicePath() with AppendDevicePathNode():

  CreatePlatformBootOptionFromGuid()
    DevicePath = AppendDevicePathNode(...)                  #1
    EfiBootManagerInitializeLoadOption (... DevicePath ...)
      DuplicateDevicePath(FilePath=DevicePath)              #2

Again, AppendDevicePathNode() produces dynamic object #1, similarly to
ConvertTextToDevicePath().

Thanks
Laszlo


      reply	other threads:[~2018-04-26 10:20 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-25  4:59 [PATCH edk2-platforms v5 0/2] add platform boot options Haojian Zhuang
2018-04-25  4:59 ` [PATCH edk2-platforms v5 1/2] Platform/HiKey960: register predefined " Haojian Zhuang
2018-04-25  4:59 ` [PATCH edk2-platforms v5 2/2] Platform/HiKey: create 4 " Haojian Zhuang
2018-04-25 16:10 ` [PATCH edk2-platforms v5 0/2] add platform " Laszlo Ersek
2018-04-26  3:12   ` Haojian Zhuang
2018-04-26 10:20     ` Laszlo Ersek [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=32e983cd-ec8e-43bf-4db8-93949a6b0894@redhat.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox