sprintf segfaults with too high precision
|ruby -v:||-||Backport:||1.9.3: DONE, 2.0.0: DONE|
In any Ruby version (attempted with 1.8.7, 1.9.3, and 2.0.0), specifying a very large precision in sprintf can cause a segmentation fault.
The following code will cause the segmentation fault.
"%.99999f" % 10
The number to cause a segfault is dependent on the system. On my laptop, any number above 1100 would cause it, and on an EC2 micro instance, around 2500 was the limit.
#3 Updated by Utkarsh Kukreti 7 months ago
I'm trying to write a patch for this (my first contribution actually), and I'll really appreciate some help.
I've found the cause -- the buffer sent to
cvt() function in vsnprintf.c is allocated on the stack with a fixed size of
#define BUF (MAXEXP+MAXFRACT+1) here which on my machine is
1024 + 64 + 1 == 1089, and the data is written to it without any bounds check, which causes the segfault.
I can think of two possible solutions:
- Limit the precision a user can specify on a call to sprintf to
mallocthe actual required memory when it's greater than the defined constant
freeit before returning from the function.
I think (2) is the best solution here.
What do you all think? Also, what functions should I use to allocate/free memory inside
#6 Updated by Nobuyoshi Nakada 7 months ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
This issue was solved with changeset r42918.
Aaron, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
vsnprintf.c: fix buffer overflow
- vsnprintf.c (MAXEXP, MAXFRACT): calculate depending on constants in float.h.
- vsnprintf.c (BSD_vfprintf): limit length for cvt() to get rid of buffer overflow. [Bug #8864]
- vsnprintf.c (exponent): make expbuf size more precise.