All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Salter <msalter@redhat.com>
To: Matt Fleming <matt@codeblueprint.co.uk>,
	Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org,
	"K. Y. Srinivasan" <kys@microsoft.com>
Subject: Re: [PATCH] efi: fix for_each_efi_memory_desc_in_map() for empty memmaps
Date: Wed, 25 May 2016 17:00:10 -0400	[thread overview]
Message-ID: <1464210010.15044.15.camel@redhat.com> (raw)
In-Reply-To: <20160525204805.GE2984@codeblueprint.co.uk>

On Wed, 2016-05-25 at 21:48 +0100, Matt Fleming wrote:
> (Cc'ing Mark, the original author)
> 
> On Wed, 25 May, at 04:36:55PM, Vitaly Kuznetsov wrote:
> > 
> > Commit 78ce248faa3c ("efi: Iterate over efi.memmap in
> > for_each_efi_memory_desc()") introduced a regression for systems booted
> > with 'noefi' kernel option. In particular, I observe early kernel hang in
> > efi_find_mirror() on for_each_efi_memory_desc() call. As we don't have
> > efi memmap we enter this iterator with the following parameters:
> > 
> > efi.memmap.map = 0, efi.memmap.map_end = 0, efi.memmap.desc_size = 28
> > 
> > for_each_efi_memory_desc_in_map() does the following comparison:
> > 
> > (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size);
> > 
> > where md = 0, (m)->map_end = 0 and (m)->desc_size = 28 but when we subtract
> > something from a NULL pointer wrap around happens and we end up returning
> > invalid pointer.
> > 
> > Fixes: 78ce248faa3c ("efi: Iterate over efi.memmap in for_each_efi_memory_desc()")
> > Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> > ---
> >  include/linux/efi.h | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/linux/efi.h b/include/linux/efi.h
> > index c2db3ca..229ccb5 100644
> > --- a/include/linux/efi.h
> > +++ b/include/linux/efi.h
> > @@ -1005,7 +1005,8 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm,
> >  /* Iterate through an efi_memory_map */
> >  #define for_each_efi_memory_desc_in_map(m, md)				   \
> >  	for ((md) = (m)->map;						   \
> > -	     (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size); \
> > +	     (efi_memory_desc_t *)((md) + (m)->desc_size) <=		   \
> > +		     (efi_memory_desc_t *)(m)->map_end;			   \
> >  	     (md) = (void *)(md) + (m)->desc_size)
> Curse C type casting!
> 
> You're adding m->desc_size to a (efi_memory_desc_t *) which is 40
> bytes. You need the below to avoid breaking regular EFI boot.
> 
> But yeah, this looks like a fine fix. Mark, any concerns?

No concerns. It looks like the right thing to do.

> 
> ---
> 
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index d8ab480b1089..3a3f8d8bd9be 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -1026,7 +1026,7 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm,
>  /* Iterate through an efi_memory_map */
>  #define for_each_efi_memory_desc_in_map(m, md)				   \
>  	for ((md) = (m)->map;						   \
> -	     (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size); \
> +	     ((void *)(md) + (m)->desc_size) <=	(m)->map_end;		   \
>  	     (md) = (void *)(md) + (m)->desc_size)
>  
>  /**

WARNING: multiple messages have this Message-ID (diff)
From: Mark Salter <msalter-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: Matt Fleming
	<matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>,
	Vitaly Kuznetsov
	<vkuznets-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	"K. Y. Srinivasan" <kys-0li6OtcxBFHby3iVrkZq2A@public.gmane.org>
Subject: Re: [PATCH] efi: fix for_each_efi_memory_desc_in_map() for empty memmaps
Date: Wed, 25 May 2016 17:00:10 -0400	[thread overview]
Message-ID: <1464210010.15044.15.camel@redhat.com> (raw)
In-Reply-To: <20160525204805.GE2984-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>

On Wed, 2016-05-25 at 21:48 +0100, Matt Fleming wrote:
> (Cc'ing Mark, the original author)
> 
> On Wed, 25 May, at 04:36:55PM, Vitaly Kuznetsov wrote:
> > 
> > Commit 78ce248faa3c ("efi: Iterate over efi.memmap in
> > for_each_efi_memory_desc()") introduced a regression for systems booted
> > with 'noefi' kernel option. In particular, I observe early kernel hang in
> > efi_find_mirror() on for_each_efi_memory_desc() call. As we don't have
> > efi memmap we enter this iterator with the following parameters:
> > 
> > efi.memmap.map = 0, efi.memmap.map_end = 0, efi.memmap.desc_size = 28
> > 
> > for_each_efi_memory_desc_in_map() does the following comparison:
> > 
> > (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size);
> > 
> > where md = 0, (m)->map_end = 0 and (m)->desc_size = 28 but when we subtract
> > something from a NULL pointer wrap around happens and we end up returning
> > invalid pointer.
> > 
> > Fixes: 78ce248faa3c ("efi: Iterate over efi.memmap in for_each_efi_memory_desc()")
> > Signed-off-by: Vitaly Kuznetsov <vkuznets-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > ---
> >  include/linux/efi.h | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/linux/efi.h b/include/linux/efi.h
> > index c2db3ca..229ccb5 100644
> > --- a/include/linux/efi.h
> > +++ b/include/linux/efi.h
> > @@ -1005,7 +1005,8 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm,
> >  /* Iterate through an efi_memory_map */
> >  #define for_each_efi_memory_desc_in_map(m, md)				   \
> >  	for ((md) = (m)->map;						   \
> > -	     (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size); \
> > +	     (efi_memory_desc_t *)((md) + (m)->desc_size) <=		   \
> > +		     (efi_memory_desc_t *)(m)->map_end;			   \
> >  	     (md) = (void *)(md) + (m)->desc_size)
> Curse C type casting!
> 
> You're adding m->desc_size to a (efi_memory_desc_t *) which is 40
> bytes. You need the below to avoid breaking regular EFI boot.
> 
> But yeah, this looks like a fine fix. Mark, any concerns?

No concerns. It looks like the right thing to do.

> 
> ---
> 
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index d8ab480b1089..3a3f8d8bd9be 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -1026,7 +1026,7 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm,
>  /* Iterate through an efi_memory_map */
>  #define for_each_efi_memory_desc_in_map(m, md)				   \
>  	for ((md) = (m)->map;						   \
> -	     (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size); \
> +	     ((void *)(md) + (m)->desc_size) <=	(m)->map_end;		   \
>  	     (md) = (void *)(md) + (m)->desc_size)
>  
>  /**

  reply	other threads:[~2016-05-25 21:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-25 14:36 [PATCH] efi: fix for_each_efi_memory_desc_in_map() for empty memmaps Vitaly Kuznetsov
2016-05-25 14:36 ` Vitaly Kuznetsov
2016-05-25 20:48 ` Matt Fleming
2016-05-25 20:48   ` Matt Fleming
2016-05-25 21:00   ` Mark Salter [this message]
2016-05-25 21:00     ` Mark Salter

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=1464210010.15044.15.camel@redhat.com \
    --to=msalter@redhat.com \
    --cc=kys@microsoft.com \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matt@codeblueprint.co.uk \
    --cc=vkuznets@redhat.com \
    /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.