[prev in list] [next in list] [prev in thread] [next in thread] 

List:       oss-security
Subject:    Re: [oss-security] Interesting behavior with struct initiailization
From:       Geoff Keating <geoffk () apple ! com>
Date:       2010-11-30 2:54:22
Message-ID: 4A4ED40C-6553-4AD8-909F-7FF47E2EFEF0 () apple ! com
[Download RAW message or body]

On 25/11/2010, at 5:31 AM, Nelson Elhage wrote:

> Is it possible that the zeroing out of padding bytes by GCC is an
> implementation detail that we've been relying on, and never something
> that was intended as part of the exposed contract? Is there anyone on
> this list more qualified to comment on either the specification or
> GCC's implementation?

C99 says, in 6.2.6.1p6,

> When a value is stored in an object of structure or union type, including in a member object, \
> the bytes of the object representation that correspond to any padding bytes take unspecified \
> values.42)

and there is a specific footnote in case this wasn't clear enough:

> 42) Thus, for example, structure assignment may be implemented element-at-a-time or via \
> memcpy.


but the description goes *much* further than the footnote.  In principle, it means if you write

struct test { int a; char b; int c; } x;
memset (&x, 0, sizeof(x));
x.a = 1;

then the compiler is free to change the padding bytes after 'x.b' to whatever it likes, because \
you changed 'x.a', even though you might think you cleared them and the compiler would have no \
reason to make this change.  In practice this might manifest in the case of 

memset (&x, 0, sizeof(x));
x.a = 1; x.b = 2; x.c = 3;

by the compiler optimising out the 'memset' as a dead store.

Since C99 says it is unspecified, you'd have to look at the GCC documentation, and I don't see \
any specification there either.

In practise, GCC does exactly this, with its own built-in initializer expansion.  If you turn \
on the right debugging flag (I think -fdump-tree-original -fdump-tree-gimple is what you want), \
you can see GCC turn

    struct test arg = {.a=1};
  use (&arg);
    struct test arg2 = {.a=1, .b=2, .c=3};
  use (&arg2);

into

  arg = {};
  arg.a = 1;
  use (&arg);
  arg2.a = 1;
  arg2.b = 2;
  arg2.c = 3;
  use (&arg2);

The comment in the code (in gimplify.c) explains that the side-effect of clearing unused bytes \
is definitely not intentional, it reads:

   Note that we still need to clear any elements that don't have explicit
   initializers, so if not all elements are initialized we keep the
   original MODIFY_EXPR, we just remove all of the constructor elements.

and

        /* ??? This bit ought not be needed.  For any element not present
           in the initializer, we should simply set them to zero.  Except
           we'd need to *find* the elements that are not present, and that
           requires trickery to avoid quadratic compile-time behavior in
           large cases or excessive memory use in small cases.  */
        else if (num_ctor_elements < num_type_elements)
          cleared = true;


["smime.p7s" (smime.p7s)]

0	*H
 010	+0	*H
 040 0
	*H
0}10	UIL10U

StartCom Ltd.1+0)U"Secure Digital Certificate Signing1)0'U StartCom Certification \
Authority0 071024210155Z
171024210155Z010	UIL10U

StartCom Ltd.1+0)U"Secure Digital Certificate Signing1806U/StartCom Class 1 Primary \
Intermediate Client CA0"0 	*H
0
	-).2AUGo#G
B|NDRpM-B=o-we5JQpa>O.# ._<V
[~**pz~3WG.ᘟMlr[<Ce6fqO"uxfWN#uic \
gkv$Lb%y`_{`xK'GN00U00U \
0USr풜\|~5NԸQ0U#0N@[i04hCA0f+Z0X0'+0ht \
tp://ocsp.startssl.com/ca0-+0!http://www.startssl.com/sfsca.crt0[UT0R0' % \
#!http://www.startssl.com/sfsca.crl0' % #!http://crl.startssl.com/sfsca.crl0U \
y0w0u+70f0.+"http://www.startssl.com/policy.pdf04+(http://www.startssl.com/intermediate.pdf0
 	*H
ʳ% [mD4_  NO֩s;{}FGhK嘖?6xF&m>ܟv-SʃbIuj5_aG꺓 \
ufQ;ъ>Bٵvw-kpNz㗱b{A%JŋnVx,ю@w|ZQd 
+tV`V]GB}?]rPtX]C3-Klβ2ߺDI%ҙ`BOno \
ߥ^{?$9ˣ;>9v܃qNfO79O++T'N="H=NxBhՐIBv \
TyRƋ%K}/ٞ]!RZ0p&QlV@PL3DTaVD{>.\Iu^d}Jfa
 DӮV@QJXo.>ӭJƦ~15Xy00| 0
	*H
010	UIL10U

StartCom Ltd.1+0)U"Secure Digital Certificate Signing1806U/StartCom Class 1 Primary \
Intermediate Client CA0 101015081802Z
111016020109Z01 0U
275259-ENsrFL88plVwU9Eh10U
Persona Not Validated1)0'U StartCom Free Certificate Member10	*H
	geoffk@apple.com0"0
	*H
0
xGh%Mo/6K+~L_'ks僴>ޢEM4]ުͨ@	Vp˛">e,l5u5D:bnU'*aҾK(_4Ι	[v?@ED}t!Kߧ4 \
B`*EAL.OX*S@˾kb}&S~'!jXԡi{حM|b|"nZ9)2N<C0} \
!^hb7LXW%CbhA\z00	U00U0U%0+ \
+0UWdrWkPp0U#0Sr풜\|~5NԸQ0U0geoffk@apple.com0BU \
90501+70 \
0.+"http://www.startssl.com/policy.pdf04+(http://www.startssl.com/intermediate.pdf0+00
 StartCom Ltd.0Limited Liability, see section *Legal Limitations* of the StartCom \
Certification Authority Policy available at http://www.startssl.com/policy.pdf0cU\0Z0+ ) \
'%http://www.startssl.com/crtu1-crl.crl0+ ) \
'%http://crl.startssl.com/crtu1-crl.crl0+009+0-http://ocsp.startssl.com \
/sub/class1/client/ca0B+06http://www.startssl.com/certs/sub.class1.client.ca.crt0#U0http://www.startssl.com/0
 	*H
e+# FZ#ú-vаs!O{"m
HcliuaVn&Ppy_5mgF!uD[]`O$cSϢs+xov\C'?(@EK4+c4(D>9yG9Bu
 @
襌GVpqmk1Tز˰AxGA8MY \
۝#JfGXI-~9Mfjhl[+}L.X.Gޒ&x!/:1o0k0010	UIL10U
 
StartCom Ltd.1+0)U"Secure Digital Certificate Signing1806U/StartCom Class 1 Primary \
Intermediate Client CA0	+ 0	*H 	1	*H
0	*H
	1
101130025424Z0#	*H
	1Ga"bϹન=zi0	+710010	UIL10U

StartCom Ltd.1+0)U"Secure Digital Certificate Signing1806U/StartCom Class 1 Primary \
Intermediate Client CA0*H 	1 010	UIL10U

StartCom Ltd.1+0)U"Secure Digital Certificate Signing1806U/StartCom Class 1 Primary \
Intermediate Client CA0 	*H
=rLaU&?w2;?ۈ)j4Q<0\0JX㣄HˏI:Evu*zS. \
.O]<^w?A:qv@,F55hh4s]ъ2c6E3&(i~2SZHB͐GV:@7#N^N7
 Frא"mPɭHQjrX}ZDm.(.>j>



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic