All of lore.kernel.org
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: u-boot@lists.denx.de
Subject: [PATCH 1/1] efi_loader: fix get_last_capsule()
Date: Wed, 10 Feb 2021 15:43:25 +0900	[thread overview]
Message-ID: <20210210064325.GA52561@laputa> (raw)
In-Reply-To: <5C5936E1-0746-4D03-97BD-F272D3D67681@gmx.de>

On Wed, Feb 10, 2021 at 07:05:10AM +0100, Heinrich Schuchardt wrote:
> Am 10. Februar 2021 01:38:38 MEZ schrieb AKASHI Takahiro <takahiro.akashi@linaro.org>:
> >On Tue, Feb 09, 2021 at 09:37:42PM +0100, Heinrich Schuchardt wrote:
> >> fix get_last_capsule() leads to writes beyond the stack allocated
> >buffer.
> >> This was indicated when enabling the stack protector.
> >> 
> >> utf16_utf8_strcpy() only stops copying when reaching '\0'. The
> >current
> >> invocation always writes beyond the end of value[].
> >> 
> >> The output length of utf16_utf8_strcpy() may be longer than the
> >number of
> >> UTF-16 tokens. E.g has "Capsule????" has 11 UTF-16 tokens but 15
> >UTF-8
> >
> >First of all, "CapsuleLast" is a read-only variable from user's
> >viewpoint,
> >and is maintained solely by efi code. Then its value is expected to
> >always
> >be sane.
> >The case you suggested above is quite unlikely.
> 
> What happens if the user tries to create a variable of the same name, e.g. in the variable store on disk?

If this is your concern, the best solution would be to prohibit
users to create system-managed (read-only) variables, like CapsuleLast.

If a user can create such a variable with an arbitrary value,
it will hurt the system's integrity.

> 
> >
> >Although I don't think we need this patch,
> 
> Why do you think the patch is not necessary given that the current code is writing ouside buffers?

My assumption here is, as I said,
> >First of all, "CapsuleLast" is a read-only variable from user's
> >viewpoint,
> >and is maintained solely by efi code. Then its value is expected to
> >always
> >be sane.

-Takahiro Akashi


> >
> >> tokens. Hence, using utf16_utf8_strcpy() without checking the input
> >may
> >> lead to further writes beyond value[].
> >> 
> >> The current invocation of strict_strtoul() reads beyond the end of
> >value[].
> >> 
> >> A non-hexadecimal value after "Capsule" (e.g. "CapsuleZZZZ") must
> >result in
> >> an error. We cat catch this by checking the return value of
> >strict_strtoul().
> >> 
> >> A value that is too short after "Capsule" (e.g. "Capsule0") must
> >result in
> >> an error. We must check the string length of value[].
> >> 
> >> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> >> ---
> >>  lib/efi_loader/efi_capsule.c | 18 +++++++++++++-----
> >>  1 file changed, 13 insertions(+), 5 deletions(-)
> >> 
> >> diff --git a/lib/efi_loader/efi_capsule.c
> >b/lib/efi_loader/efi_capsule.c
> >> index d39d731080..0017f0c0db 100644
> >> --- a/lib/efi_loader/efi_capsule.c
> >> +++ b/lib/efi_loader/efi_capsule.c
> >> @@ -42,20 +42,28 @@ static struct efi_file_handle *bootdev_root;
> >>  static __maybe_unused unsigned int get_last_capsule(void)
> >>  {
> >>  	u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */
> >> -	char value[11], *p;
> >> +	char value[5];
> >>  	efi_uintn_t size;
> >>  	unsigned long index = 0xffff;
> >>  	efi_status_t ret;
> >> +	int i;
> >> 
> >>  	size = sizeof(value16);
> >>  	ret = efi_get_variable_int(L"CapsuleLast",
> >&efi_guid_capsule_report,
> >>  				   NULL, &size, value16, NULL);
> >> -	if (ret != EFI_SUCCESS || u16_strncmp(value16, L"Capsule", 7))
> >> +	if (ret != EFI_SUCCESS || size != 22 ||
> >> +	    u16_strncmp(value16, L"Capsule", 7))
> >>  		goto err;
> >> +	for (i = 0; i < 4; ++i) {
> >> +		u16 c = value16[i + 7];
> >> 
> >> -	p = value;
> >> -	utf16_utf8_strcpy(&p, value16);
> >> -	strict_strtoul(&value[7], 16, &index);
> >> +		if (!c)
> >> +			goto err;
> >
> >Is this check necessary assuming size == 22?
> 
> Ok. Instead we should check for > 0x7f here to avoid illegal codes.
> 
> Best regards
> 
> Heinrich
> 
> >
> >
> >> +		value[i] = c;
> >
> >You are implicitly casting the value from u16 to u8 here.
> >This may lead to making an illegal code legal.
> >
> >-Takahiro Akashi
> >
> >> +	}
> >> +	value[4] = 0;
> >> +	if (strict_strtoul(value, 16, &index))
> >> +		index = 0xffff;
> >>  err:
> >>  	return index;
> >>  }
> >> --
> >> 2.30.0
> >> 
> 

  reply	other threads:[~2021-02-10  6:43 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-09 20:37 [PATCH 1/1] efi_loader: fix get_last_capsule() Heinrich Schuchardt
2021-02-10  0:38 ` AKASHI Takahiro
2021-02-10  6:05   ` Heinrich Schuchardt
2021-02-10  6:43     ` AKASHI Takahiro [this message]
2021-02-10  6:49       ` Heinrich Schuchardt
2021-02-10  6:52       ` Heinrich Schuchardt

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=20210210064325.GA52561@laputa \
    --to=takahiro.akashi@linaro.org \
    --cc=u-boot@lists.denx.de \
    /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.