All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lukas Wunner <lukas-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
To: Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Andreas Noever
	<andreas.noever-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Pierre Moreau <pierre.morrow-GANU6spQydw@public.gmane.org>,
	reverser-P1ImLx+pFc0@public.gmane.org,
	grub-devel-mXXj517/zsQ@public.gmane.org,
	x86-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH 1/6] efi: Retrieve Apple device properties
Date: Fri, 5 Aug 2016 13:42:19 +0200	[thread overview]
Message-ID: <20160805114219.GA4952@wunner.de> (raw)
In-Reply-To: <20160804151345.GM3636-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>

On Thu, Aug 04, 2016 at 04:13:45PM +0100, Matt Fleming wrote:
> On Thu, 28 Jul, at 02:25:41AM, Lukas Wunner wrote:
> > diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
> > index ff574da..7262ee4 100644
> > --- a/arch/x86/boot/compressed/eboot.c
> > +++ b/arch/x86/boot/compressed/eboot.c
> > @@ -571,6 +571,55 @@ free_handle:
> >  	efi_call_early(free_pool, pci_handle);
> >  }
> >  
> > +static void retrieve_apple_device_properties(struct boot_params *params)
> > +{
> > +	efi_guid_t guid = APPLE_PROPERTIES_PROTOCOL_GUID;
> > +	struct setup_data *data, *new;
> > +	efi_status_t status;
> > +	void *properties;
> > +	u32 size = 0;
> > +
> > +	status = efi_early->call(
> > +			(unsigned long)sys_table->boottime->locate_protocol,
> > +			&guid, NULL, &properties);
> > +	if (status != EFI_SUCCESS)
> > +		return;
> > +
> > +	do {
> > +		status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
> > +			size + sizeof(struct setup_data), &new);
> > +		if (status != EFI_SUCCESS) {
> > +			efi_printk(sys_table,
> > +				   "Failed to alloc mem for properties\n");
> > +			return;
> > +		}
> > +		status = efi_early->call(efi_early->is64 ?
> > +			((apple_properties_protocol_64 *)properties)->get_all :
> > +			((apple_properties_protocol_32 *)properties)->get_all,
> > +			properties, new->data, &size);
> > +		if (status == EFI_BUFFER_TOO_SMALL)
> > +			efi_call_early(free_pool, new);
> > +	} while (status == EFI_BUFFER_TOO_SMALL);
> 
> Is this looping really required? Do we not know ahead of time what we
> expect the size to be? Writing this as a potentially infinite loop (if
> broken firmware always returns EFI_BUFFER_TOO_SMALL) is a bad idea.

macOS' bootloader does exactly the same. So if the firmware was broken
in this way, macOS wouldn't boot and it's unlikely that Apple would
ship it. The code is not executed on non-Macs (due to the memcmp for
sys_table->fw_vendor[] == u"Apple" in efi_main()).

Looks like this in /usr/standalone/i386/boot.efi:
58b9         mov        rbx, 0x8000000000000005		; EFI_BUFFER_TOO_SMALL
...
58e6         mov        rcx, qword [ss:rbp+var_38]	; properties protocol
58ea         mov        rdx, rdi			; properties buffer
58ed         mov        r8, rsi				; buffer len
58f0         call       qword [ds:rcx+0x20]		; properties->get_all
58f3         cmp        rax, rbx
58f6         je         0x58c5				; infinite loop

And the code in the corresponding ->get_all function in the EFI driver
is such that it only returns either EFI_SUCCESS or EFI_BUFFER_TOO_SMALL.

So I could cap the number of loop iterations but it would be pointless.

I also checked the bootloader they shipped with OS X 10.6 (2009), they
used Universal EFI binaries back then (x86_64 + i386) in order to support
the very first Intel Macs of 2006. Found the same infinite loop there.

The reason for the loop is that the number of device properties is
dynamic. E.g. each attached Thunderbolt device is assigned 3 properties.
If a Thunderbolt device is plugged in between a first loop iteration
(to obtain the size) and a second loop iteration (to fill the buffer),
EFI_BUFFER_TOO_SMALL is returned and a third loop iteration is needed.

Thanks,

Lukas

WARNING: multiple messages have this Message-ID (diff)
From: Lukas Wunner <lukas@wunner.de>
To: Matt Fleming <matt@codeblueprint.co.uk>
Cc: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org,
	Andreas Noever <andreas.noever@gmail.com>,
	Pierre Moreau <pierre.morrow@free.fr>,
	reverser@put.as, grub-devel@gnu.org, x86@kernel.org,
	linux-acpi@vger.kernel.org
Subject: Re: [PATCH 1/6] efi: Retrieve Apple device properties
Date: Fri, 5 Aug 2016 13:42:19 +0200	[thread overview]
Message-ID: <20160805114219.GA4952@wunner.de> (raw)
In-Reply-To: <20160804151345.GM3636@codeblueprint.co.uk>

On Thu, Aug 04, 2016 at 04:13:45PM +0100, Matt Fleming wrote:
> On Thu, 28 Jul, at 02:25:41AM, Lukas Wunner wrote:
> > diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
> > index ff574da..7262ee4 100644
> > --- a/arch/x86/boot/compressed/eboot.c
> > +++ b/arch/x86/boot/compressed/eboot.c
> > @@ -571,6 +571,55 @@ free_handle:
> >  	efi_call_early(free_pool, pci_handle);
> >  }
> >  
> > +static void retrieve_apple_device_properties(struct boot_params *params)
> > +{
> > +	efi_guid_t guid = APPLE_PROPERTIES_PROTOCOL_GUID;
> > +	struct setup_data *data, *new;
> > +	efi_status_t status;
> > +	void *properties;
> > +	u32 size = 0;
> > +
> > +	status = efi_early->call(
> > +			(unsigned long)sys_table->boottime->locate_protocol,
> > +			&guid, NULL, &properties);
> > +	if (status != EFI_SUCCESS)
> > +		return;
> > +
> > +	do {
> > +		status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
> > +			size + sizeof(struct setup_data), &new);
> > +		if (status != EFI_SUCCESS) {
> > +			efi_printk(sys_table,
> > +				   "Failed to alloc mem for properties\n");
> > +			return;
> > +		}
> > +		status = efi_early->call(efi_early->is64 ?
> > +			((apple_properties_protocol_64 *)properties)->get_all :
> > +			((apple_properties_protocol_32 *)properties)->get_all,
> > +			properties, new->data, &size);
> > +		if (status == EFI_BUFFER_TOO_SMALL)
> > +			efi_call_early(free_pool, new);
> > +	} while (status == EFI_BUFFER_TOO_SMALL);
> 
> Is this looping really required? Do we not know ahead of time what we
> expect the size to be? Writing this as a potentially infinite loop (if
> broken firmware always returns EFI_BUFFER_TOO_SMALL) is a bad idea.

macOS' bootloader does exactly the same. So if the firmware was broken
in this way, macOS wouldn't boot and it's unlikely that Apple would
ship it. The code is not executed on non-Macs (due to the memcmp for
sys_table->fw_vendor[] == u"Apple" in efi_main()).

Looks like this in /usr/standalone/i386/boot.efi:
58b9         mov        rbx, 0x8000000000000005		; EFI_BUFFER_TOO_SMALL
...
58e6         mov        rcx, qword [ss:rbp+var_38]	; properties protocol
58ea         mov        rdx, rdi			; properties buffer
58ed         mov        r8, rsi				; buffer len
58f0         call       qword [ds:rcx+0x20]		; properties->get_all
58f3         cmp        rax, rbx
58f6         je         0x58c5				; infinite loop

And the code in the corresponding ->get_all function in the EFI driver
is such that it only returns either EFI_SUCCESS or EFI_BUFFER_TOO_SMALL.

So I could cap the number of loop iterations but it would be pointless.

I also checked the bootloader they shipped with OS X 10.6 (2009), they
used Universal EFI binaries back then (x86_64 + i386) in order to support
the very first Intel Macs of 2006. Found the same infinite loop there.

The reason for the loop is that the number of device properties is
dynamic. E.g. each attached Thunderbolt device is assigned 3 properties.
If a Thunderbolt device is plugged in between a first loop iteration
(to obtain the size) and a second loop iteration (to fill the buffer),
EFI_BUFFER_TOO_SMALL is returned and a third loop iteration is needed.

Thanks,

Lukas

  parent reply	other threads:[~2016-08-05 11:42 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-27 11:20 [PATCH 0/6] Apple device properties Lukas Wunner
2016-07-27 11:20 ` Lukas Wunner
2016-07-27 11:20 ` [PATCH 1/6] efi: Retrieve " Lukas Wunner
2016-07-27 11:20   ` Lukas Wunner
2016-07-30 19:16   ` Andrei Borzenkov
2016-07-30 19:16     ` Andrei Borzenkov
2016-08-04 15:13   ` Matt Fleming
2016-08-04 15:13     ` Matt Fleming
     [not found]     ` <20160804151345.GM3636-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
2016-08-05 11:42       ` Lukas Wunner [this message]
2016-08-05 11:42         ` Lukas Wunner
2016-08-05 12:06         ` Matt Fleming
2016-07-27 11:20 ` [PATCH 6/6] thunderbolt: Use Device ROM retrieved from EFI Lukas Wunner
2016-07-27 11:20 ` [PATCH 3/6] efi: Add device path parser Lukas Wunner
2016-07-27 11:20 ` [PATCH 5/6] efi: Assign Apple device properties Lukas Wunner
     [not found]   ` <a0edd928ab099682c2cb4c4544c599573144d03a.1469616641.git.lukas-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
2016-08-04 15:52     ` Matt Fleming
2016-08-04 15:52       ` Matt Fleming
2016-07-27 11:20 ` [PATCH 2/6] ACPI / bus: Make acpi_get_first_physical_node() public Lukas Wunner
2016-08-17  0:38   ` Rafael J. Wysocki
     [not found]     ` <1821462.QyPXGhZaWJ-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2016-09-12 22:03       ` Rafael J. Wysocki
2016-09-12 22:03         ` Rafael J. Wysocki
2016-07-27 11:20 ` [PATCH 4/6] driver core: Don't leak secondary fwnode on device removal Lukas Wunner
2016-07-27 11:20   ` Lukas Wunner
2016-08-17  0:38   ` Rafael J. Wysocki
2016-08-30  9:03     ` Lukas Wunner
2016-09-12 22:03       ` Rafael J. Wysocki
2016-07-27 23:48 ` [PATCH 0/6] Apple device properties Rafael J. Wysocki
2016-07-27 23:48   ` Rafael J. Wysocki
2016-07-28  0:25 ` [PATCH 5/6] efi: Assign " Lukas Wunner
2016-07-28  0:25 ` [PATCH 2/6] ACPI / bus: Make acpi_get_first_physical_node() public Lukas Wunner
2016-07-28  0:25 ` [PATCH 4/6] driver core: Don't leak secondary fwnode on device removal Lukas Wunner
2016-07-28  0:25 ` [PATCH 1/6] efi: Retrieve Apple device properties Lukas Wunner
2016-07-28  0:25 ` [PATCH 6/6] thunderbolt: Use Device ROM retrieved from EFI Lukas Wunner
2016-07-28  0:25 ` [PATCH 3/6] efi: Add device path parser Lukas Wunner
2016-08-04 14:57 ` [PATCH 0/6] Apple device properties Matt Fleming
2016-08-09 13:38   ` Lukas Wunner
2016-08-15 11:54     ` Matt Fleming
2016-08-15 16:13       ` Lukas Wunner
2016-08-18 20:34         ` Matt Fleming
2016-08-22  9:58           ` Lukas Wunner
2016-08-22  9:58             ` Lukas Wunner
2016-08-24 19:49             ` Matt Fleming

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-all 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=20160805114219.GA4952@wunner.de \
    --to=lukas-jfq808j9c/izqb+pc5nmwq@public.gmane.org \
    --cc=andreas.noever-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=grub-devel-mXXj517/zsQ@public.gmane.org \
    --cc=linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org \
    --cc=pierre.morrow-GANU6spQydw@public.gmane.org \
    --cc=reverser-P1ImLx+pFc0@public.gmane.org \
    --cc=x86-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.