From: Matthew Garrett <mjg59@srcf.ucam.org>
To: Mike Waychison <mikew@google.com>
Cc: linux-kernel@vger.kernel.org, x86@kernel.org, hpa@zytor.com
Subject: Re: [PATCH 3/4] EFI: Add support for variables longer than 1024 bytes
Date: Wed, 14 Dec 2011 22:39:50 +0000 [thread overview]
Message-ID: <20111214223950.GA29264@srcf.ucam.org> (raw)
In-Reply-To: <CAGTjWtCpt_1h6XMwCFkx1TQnQbagtSuFBejcp6XNr4yhKgNuLg@mail.gmail.com>
On Wed, Dec 14, 2011 at 02:14:27PM -0800, Mike Waychison wrote:
> > static efi_status_t
> > -get_var_data_locked(struct efivars *efivars, struct efi_variable *var)
> > +get_var_data_locked(struct efivars *efivars, struct extended_efi_variable **var)
> > {
> > efi_status_t status;
> > + unsigned long length;
> > +
> > + if (!*var)
> > + *var = kmalloc(sizeof(struct extended_efi_variable), GFP_KERNEL);
>
> Aren't we holding a spinlock here?
Good point.
> > +
> > + (*var)->header.DataSize = 0;
> > + status = efivars->ops->get_variable((*var)->header.VariableName,
> > + &(*var)->header.VendorGuid,
> > + &(*var)->header.Attributes,
> > + &(*var)->header.DataSize,
> > + (*var)->Data);
>
> This doesn't look right. ->Data here is after the Data[1024] buffer
> embedded in (*var)->header, and a read into this buffer will corrupt
> the heap.
DataSize is 0, so we'll never actually read anything back here.
> > +
> > + if (status == EFI_BUFFER_TOO_SMALL) {
> > + *var = krealloc(*var, sizeof(struct extended_efi_variable) +
> > + (*var)->header.DataSize, GFP_KERNEL);
> > + status = efivars->ops->get_variable((*var)->header.VariableName,
> > + &(*var)->header.VendorGuid,
> > + &(*var)->header.Attributes,
> > + &(*var)->header.DataSize,
> > + (*var)->Data);
> > + }
> > +
> > + length = ((*var)->header.DataSize < 1024) ? (*var)->header.DataSize :
> > + 1024;
> > +
> > + memcpy(&(*var)->header.Data, &(*var)->Data, length);
>
> This memcpy clobbers the header.Data with the corrupted data when we
> didn't use the second path.
We'll always follow the second path providing there's actually data to
read back. If there isn't then length will be 0.
> > + if (count == sizeof(struct efi_variable)) {
> > + tmp_var = (struct efi_variable *)buf;
> > + new_var = kmalloc(sizeof(struct efi_variable) +
> > + tmp_var->DataSize, GFP_KERNEL);
> > + memcpy(&new_var->header, tmp_var, sizeof(struct efi_variable));
> > + memcpy(&new_var->Data, tmp_var->Data, tmp_var->DataSize);
> > + } else if (count > sizeof(struct efi_variable)) {
> > + new_var = (struct extended_efi_variable *)buf;
> > + } else {
> > return -EINVAL;
> > + }
>
> Ugh. This is difficult to follow, and complicates the memory freeing path :(
Entirely agreed.
> We need to be careful here. The store_raw ABI is broken, in the sense
> that the ABI from compat mode differs from that in 32bit mode (there
> is a long in the efi_variable structure which changes the offsets). I
> don't know how to fix it properly and still maintain proper ABI
> compatibility.
True.
> What are your thoughts on _not_ wrapping efi_variable with
> extended_efi_variable, and instead just using a
> "internal_efi_variable" structure that we copy stuff into/outof. I
> think that would make the memory management for dealing with the
> different sizes a lot easier to follow.
Hm. I think that'd only work if we expose a new interface. Writes would
be easy enough to handle, but reads still need to work for old apps.
--
Matthew Garrett | mjg59@srcf.ucam.org
next prev parent reply other threads:[~2011-12-14 22:39 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-14 21:06 Update UEFI variable support Matthew Garrett
2011-12-14 21:06 ` [PATCH 1/4] uefi: Populate runtime_version Matthew Garrett
2011-12-14 21:06 ` [PATCH 2/4] efi: Only create sysfs entries while booting or running Matthew Garrett
2011-12-14 21:32 ` Mike Waychison
2011-12-14 21:06 ` [PATCH 3/4] EFI: Add support for variables longer than 1024 bytes Matthew Garrett
2011-12-14 22:14 ` Mike Waychison
2011-12-14 22:39 ` Matthew Garrett [this message]
2011-12-14 22:44 ` H. Peter Anvin
2011-12-14 22:57 ` Matthew Garrett
2011-12-14 22:58 ` H. Peter Anvin
2011-12-15 15:44 ` Matthew Garrett
2011-12-14 22:57 ` Mike Waychison
2011-12-14 23:00 ` H. Peter Anvin
2011-12-14 23:06 ` Mike Waychison
2011-12-14 23:22 ` H. Peter Anvin
2011-12-14 23:24 ` Mike Waychison
2011-12-15 15:43 ` Matthew Garrett
2011-12-15 15:46 ` H. Peter Anvin
2011-12-15 15:48 ` Matthew Garrett
2011-12-14 21:06 ` [PATCH 4/4] EFI: Add support for QueryVariableInfo() call Matthew Garrett
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=20111214223950.GA29264@srcf.ucam.org \
--to=mjg59@srcf.ucam.org \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mikew@google.com \
--cc=x86@kernel.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.