public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Jordan Justen" <jordan.l.justen@intel.com>
To: Andrew Fish <afish@apple.com>, Laszlo Ersek <lersek@redhat.com>,
	devel@edk2.groups.io
Cc: devel@edk2.groups.io, Mike Kinney <michael.d.kinney@intel.com>,
	Liming Gao <liming.gao@intel.com>
Subject: Re: [edk2-devel] [PATCH 02/10] MdePkg/PiFirmwareFile: fix undefined behavior in SECTION_SIZE
Date: Wed, 17 Apr 2019 12:35:07 -0700	[thread overview]
Message-ID: <155552970738.28368.15192384950564316161@jljusten-skl> (raw)
In-Reply-To: <3a4d9e9b-ffc2-3034-dc20-29b665524b75@redhat.com>

On 2019-04-17 07:59:41, Laszlo Ersek wrote:
> On 04/17/19 13:44, Andrew Fish wrote:
> 
> > Sorry I digressed into the C specification discussion, and did not
> > deal with the patch in general. My point is the original code is legal
> > C code. If you lookup CWE-119 it is written as a restriction on what
> > the C language allows.
> >
> > As I mentioned casting to specific alignment is legal, as is defining
> > a structure that is pragma pack(1) that can make a UINT32 not be 4
> > byte aligned. Thus the cast created a legal UINT32 value. A cast to
> > *(UINT32 *) is different that a cast to (UINT32 *). The rules you
> > quote a triggered by the = and not the cast.
> >
> > Thus this is undefined behavior in C:
> >   UINT32 *Ub = (UINT32 *)gSection.Sec.Size;
> >   Size = *Ub & 0x00ffffff;
> >
> > And this is not Undefined behavior:
> >   UINT32 NotUb = *(UINT32 *)gSection.Sec.Size & 0x00ffffff;
> 
> I agree the 2nd snippet may not be UB due to alignment violations
> *alone*.
> 
> It is still UB due to violating the effective type rules.
> 
> > I also had a hard time interpreting what C spec was saying, but
> > talking to the people who write the compiler and ubsan cleared it up
> > for me. It also makes sense when you think about it. If you tell the
> > compiler *(UINT32 *) it can know to generate byte reads if the
> > hardware requires aligned access. If you do a (UINT32 *) that new
> > pointer no longer carries the information about the alignment
> > requirement. Thus the  *(UINT32 *) cast is like making a packed
> > structure.
> 
> Yes, I think I'm clear on how the alignment information is carried
> around, and when it is lost. In your first example above, due to us
> forming a separate (standalone) pointer, we lose the alignment
> information, and then the assignment is undefined due to an alignment
> violation. While in the second example, the alignment information is not
> lost, and the assignment is not undefined on an alignment basis *alone*.
> 
> However: the second assignment is *still* undefined, because it violates
> the effective type rules. Here's a more direct example for the same:
> 
> STATIC UINT64 mUint64;
> 
> int main(void)
> {
>   UINT16 *Uint16Ptr;
> 
>   Uint16Ptr = (UINT16 *)&mUint64;
>   *Uint16Ptr = 1;
>   return 0;
> }
> 
> The assignment to (*Uint16Ptr) is fine from the alignment perspective,
> but it is nevertheless undefined, because it breaks the effective type
> rules. Namely, UINT16 (the type used for the access) is not compatible
> with UINT64 (the effective type of mUint64).
> 
> Normally, we don't care about this situation in edk2 -- in fact we write
> loads of code like the above --, but we get away with that only because
> we force the toolchains to ignore the effective type rules. For GCC in
> particular, the option is "-fno-strict-aliasing".
> 
> The only reason I've posted this patch is that "cppcheck" (invoked as a
> part of "RH covscan") doesn't care about "-fno-strict-aliasing". And
> while "cppcheck" happens to report the overrun, and not the type
> punning, the way to remove the warning is to adhere to all the C rules
> in the expression, even though we have "-fno-strict-aliasing" in place.
> 
> > I agree the union is a good solution to CWE-119 and it better matches
> > the alignment requirement in the PI spec.
> 
> Thank you.
> 
> I'll wait a bit longer to see if Jordan accepts this 02/10 patch based
> on the most recent comments, and whether Liming or Mike accepts 04/10.
> 
> If Jordan remains unconvinced on SECTION_SIZE (in this 02/10 patch), and
> Liming or Mike are fine with 04/10, I can rework 02/10 to follow 04/10.
> 
> If Jordan remains unconvinced but Mike or Liming prefers the union, then
> we have a stalemate and I'll abandon the patch set.

I did have a (slight) concern about adding a typedef to a public
header that wasn't in the spec. It seemed like something that someone
somewhere might not like in case it could interfere with future
versions of the spec. According to Liming, we don't have to worry
about that.

Regarding the UINT32* discussion, I didn't think the union really
would make a difference vs skipping the union and casting the original
struct pointer directly to a UINT32*.

I can see Andrew's point that the union may add some alignment
assumptions to the dereference, so I can see how that does potentially
change something subtle. Maybe on some machines it will allow for more
efficient reading of the data with the (valid) alignment assumption.

I was also not seeing why you were saying it produced *undefined*
results. I don't think it does in our case, but when you point out
that we are aliasing data access, I can see how that quickly gets into
*undefined* territory from a compiler's perspective.

Anyway, given Liming's feedback that it is ok to add the union, I'm ok
with this patch.

-Jordan

  reply	other threads:[~2019-04-17 19:35 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-12 23:31 [PATCH 00/10] patches for some warnings raised by "RH covscan" Laszlo Ersek
2019-04-12 23:31 ` [PATCH 01/10] MdePkg/PiFirmwareFile: express IS_SECTION2 in terms of SECTION_SIZE Laszlo Ersek
2019-04-15 17:01   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-04-12 23:31 ` [PATCH 02/10] MdePkg/PiFirmwareFile: fix undefined behavior in SECTION_SIZE Laszlo Ersek
2019-04-14  7:19   ` [edk2-devel] " Jordan Justen
2019-04-15 16:15     ` Laszlo Ersek
2019-04-16  8:28       ` Liming Gao
2019-04-16  9:04       ` Jordan Justen
2019-04-16 10:59         ` Laszlo Ersek
2019-04-16 16:50           ` Philippe Mathieu-Daudé
2019-04-17 10:08             ` Laszlo Ersek
2019-04-16 18:48           ` Jordan Justen
2019-04-16 23:25             ` Andrew Fish
2019-04-17 10:29               ` Laszlo Ersek
2019-04-17 11:44                 ` Andrew Fish
2019-04-17 14:59                   ` Laszlo Ersek
2019-04-17 19:35                     ` Jordan Justen [this message]
2019-04-18  9:38                       ` Laszlo Ersek
2019-04-18 15:18                         ` Liming Gao
2019-04-17 10:01             ` Laszlo Ersek
2019-04-12 23:31 ` [PATCH 03/10] BaseTools/PiFirmwareFile: " Laszlo Ersek
2019-04-12 23:31 ` [PATCH 04/10] MdePkg/PiFirmwareFile: fix undefined behavior in FFS_FILE_SIZE Laszlo Ersek
2019-04-15 17:23   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-04-17 17:52   ` Michael D Kinney
2019-04-17 18:31     ` Michael D Kinney
2019-04-18  9:06       ` Laszlo Ersek
2019-04-17 18:31     ` Andrew Fish
2019-04-17 18:36       ` Michael D Kinney
2019-04-18  8:48         ` Laszlo Ersek
2019-04-18  8:45       ` Laszlo Ersek
2019-04-18 23:12         ` Laszlo Ersek
2019-04-18 17:20     ` Philippe Mathieu-Daudé
2019-04-18 17:59       ` Michael D Kinney
2019-04-18 18:12         ` Philippe Mathieu-Daudé
2019-04-12 23:31 ` [PATCH 05/10] OvmfPkg/Sec: fix out-of-bounds reads Laszlo Ersek
2019-04-15 17:24   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-04-12 23:31 ` [PATCH 06/10] OvmfPkg/QemuVideoDxe: avoid arithmetic on null pointer Laszlo Ersek
2019-04-12 23:31 ` [PATCH 07/10] OvmfPkg/AcpiPlatformDxe: suppress invalid "deref of undef pointer" warning Laszlo Ersek
2019-04-15 17:26   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-04-12 23:31 ` [PATCH 08/10] OvmfPkg: suppress "Value stored to ... is never read" analyzer warnings Laszlo Ersek
2019-04-14  8:03   ` [edk2-devel] " Jordan Justen
2019-04-15 16:25     ` Laszlo Ersek
2019-04-16  9:26       ` Jordan Justen
2019-04-16 11:44         ` Laszlo Ersek
2019-04-12 23:31 ` [PATCH 09/10] OvmfPkg/AcpiPlatformDxe: catch theoretical nullptr deref in Xen code Laszlo Ersek
2019-04-15 17:28   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-04-12 23:31 ` [PATCH 10/10] OvmfPkg/BasePciCapLib: suppress invalid "nullptr deref" warning Laszlo Ersek
2019-04-15 17:31   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-04-16 11:01     ` Laszlo Ersek
2019-04-12 23:36 ` [PATCH 00/10] patches for some warnings raised by "RH covscan" Ard Biesheuvel
2019-04-15 16:16   ` Laszlo Ersek
2019-04-18 14:20 ` [edk2-devel] " Laszlo Ersek

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=155552970738.28368.15192384950564316161@jljusten-skl \
    --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