NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Re: vfprintf() issue of printing negative float value



Dear christos,

Thanks for the quick reply, I have file the PR for the same.
The PR number is #44449

Please let us know if there are any issues.

Thank You,
Amol Pise


On Fri, 21 Jan 2011 14:08:36 +0530  wrote
>In article ,

nikunj badjatya  wrote:

>Hi,

>

>I have found one issue in stdio module of NetBSD library while compiling it

>for

>ARMv7a (Cortex architecture) using the GNU GCC-4.5 toolchain.

>

>The issue is while printing negative float value and the float value

>greater than 9.0, vfprintf() prints malicious characters.

>

>This can be reproduce using the sample test as below:

>

>% Cat Sample_vfprintf.c

>{{{

>

>#include 

>#include 

>

>

>void format (FILE * stream, char * format, ...)

>{

> va_list args;

> va_start (args, format);

> vfprintf (stream, format, args);

> va_end (args);

>}

>

>

>int main ()

>{

>  FILE * fp;

>

>  fp = fopen ("myfile.txt","w");

>  format (fp,"Call with %f \n",-3.14);

>  format (fp,"Call with %f \n",10.0);

>

>  fclose (fp);

>  return 0;

>}

>

>}}}

>

>

>The output on beagleboard target is:

>{{{

>-bash-3.2# ./sample_vfprintf

>

>-bash-3.2# cat myfile.txt

>

>Call with 0.,0000

>Call with :.000000

>}}}

>

>>From the above sample it is seen that for negative float value and the float

>value

>greater than 9.0, vfprintf() prints malicious characters.

>

>Later, I modified the optimization flag from O2 to O1 and build the NetBsd

>library

>and found the issue is resolved.

>

>On these lines further I have analyzed and suspected this �wrong

>optimization� may be cause

>due to �strict aliasing�

>

>The man page of GNU GCC says about �strict aliasing�:

>

>�-fstrict-aliasing

>      Allows the compiler to assume the strictest aliasing rules

>applicable to the language being compiled.

>     For C (and C++), this activates optimizations based on the type of

>ex-pressions. In particular, an

>     object of one type is assumed never to reside at the same address

>as an object of a different type,

>     unless the types are almost the same. For example, an "unsigned

>int" can alias an "int", but not a

>     "void*" or a "double". A character type may alias any other type.

>�

>

>

>To confirm this I have build NetBsd library using �-fno-strict-aliasing�

> flag with O2 optimization to suppress

>the �strict aliasing� and found the above issue is resolved.

>

>

>Further I have investigated it in the NetBsd source and found the flow of

>vfprintf as below:

>

> Vfprintf()

>  ---> __vfprintf_unlocked

>    ---> cvt()

>      ---> __dtoa

>

>

>The dtoa() implementation in NetBsd as follows:

>

>$cat src/lib/libc/gdtoa/dtoa.c

>{{{

>

>148:    if (word0(d) & Sign_bit) {

>149:        /* set sign for everything, including 0's and NaNs */

>150:        *sign = 1;

>151:        word0(d) &= ~Sign_bit; /* clear sign bit */

>152:        }

>

>}}}

>

>$cat src/lib/libc/gdtoa/gdtoaimp.h

>{{{

>176: #define ULong uint32_t

>:

>278:

>279: typedef union { double d; ULong L[2]; } U;

>:

>291: #ifdef IEEE_LITTLE_ENDIAN

>292: #define word0(x) ( /* LINTED */ (U*)&x)->L[1]

>293: #define word1(x) ( /* LINTED */ (U*)&x)->L[0]

>

>}}}

>

>

>

>Since at line:292 its breaking the strict aliasing rule. So, to bypass this

>Aliasing rules I used �__may_alias__� attribute as below.

>

>

>$cat src/lib/libc/gdtoa/gdtoaimp.h

>{{{

>- typedef union { double d; ULong L[2]; } U;

>+ typedef union { double d; ULong L[2]; } __attribute__((__may_alias__)) U;

>

>}}}

>

>With these changes vfprintf() is able to convert floating point number

>correctly without any issue.

>

>Please let me know if there are any issues.

>



Please file a PR...



Thanks,



christos


Home | Main Index | Thread Index | Old Index