Buffer overruns in printf
Subsystems (4)
cover Buffer overruns in printf
The printf family of functions in U-Boot cannot deal with a situation where the caller provides a buffer which turns out to be too small for the format string. This can result in buffer overflows, stack overflows and other bad behavior.
This patch series tidies this up in the common vsprintf.c code, and also some network code (as an example of where this might lead).
Simon Glass (2):
Add limits.h to hold basic limits
Use snprintf() in network code
Sonny Rao (2):
Add safe vsnprintf and snprintf library functions Make printf and vprintf safe from buffer overruns
common/console.c | 10 +- fs/ubifs/ubifs.h | 4 +- include/common.h | 8 ++- include/limits.h | 40 +++++++ lib/vsprintf.c | 316 ++++++++++++++++++++++++++++++++++++++++++------------ net/eth.c | 10 ++- net/net.c | 15 ++- net/nfs.c | 3 +- net/tftp.c | 3 +- 9 files changed, 323 insertions(+), 86 deletions(-) create mode 100644 include/limits.h
Signature · 1 line
1.7.3.1
PATCH 1/4 Add limits.h to hold basic limits
This brings a basic limits.h implementation into U-Boot.
--- fs/ubifs/ubifs.h | 4 +--- include/limits.h | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 include/limits.h
fs/ubifs/ubifs.h +1 -3
@@ -311,9 +311,7 @@ struct file {#define MAX_LFS_FILESIZE 0x7fffffffffffffffUL#endif -#define INT_MAX ((int)(~0U>>1)) -#define INT_MIN (-INT_MAX - 1) -#define LLONG_MAX ((long long)(~0ULL>>1)) +#include <limits.h> /* * These are the fs-independent mount-flags: up to 32 flags are supported
include/limits.h new file +40 -0
@@ -0,0 +1,40 @@ +/* +* Copyright (c) 2011 The Chromium OS Authors. +* See file CREDITS for list of people who contributed to this +* project. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#ifndef __LIMITS_H +#define __LIMITS_H + +/* Keep all our limits in one place */ + +#define USHRT_MAX ((u16)(~0U)) +#define SHRT_MAX ((s16)(USHRT_MAX>>1)) +#define SHRT_MIN ((s16)(-SHRT_MAX - 1)) +#define INT_MAX ((int)(~0U>>1)) +#define INT_MIN (-INT_MAX - 1) +#define UINT_MAX (~0U) +#define LONG_MAX ((long)(~0UL>>1)) +#define LONG_MIN (-LONG_MAX - 1) +#define ULONG_MAX (~0UL) +#define LLONG_MAX ((long long)(~0ULL>>1)) +#define LLONG_MIN (-LLONG_MAX - 1) +#define ULLONG_MAX (~0ULL) + +#endif
Signature · 1 line
1.7.3.1
PATCH 2/4 Add safe vsnprintf and snprintf library functions
In reply to Simon GlassFrom: Sonny Rao <[email protected]>
From: Sonny Rao <[email protected]>
These functions are useful in U-Boot because they allow a graceful failure rather than an unpredictable stack overflow when printf() buffers are exceeded.
Mostly copied from the Linux kernel. I copied vscnprintf and scnprintf so we can change printf and vprintf to use the safe implementation but still return the correct values.
--- include/common.h | 8 ++- lib/vsprintf.c | 316 ++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 256 insertions(+), 68 deletions(-)
include/common.h +7 -1
@@ -682,9 +682,15 @@ unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)long simple_strtol (const char *cp,char **endp,unsigned int base);void panic (const char *fmt, ...) __attribute__ ((format (__printf__,1 ,2 ), noreturn)); -int sprintf (char * buf,const char *fmt, ...) +int sprintf (char *buf,const char *fmt, ...) __attribute__ ((format (__printf__,2 ,3 ))); +int snprintf (char *buf,size_t size,const char *fmt, ...) + __attribute__ ((format (__printf__,3 ,4 ))); +int scnprintf (char *buf,size_t size,const char *fmt, ...) + __attribute__ ((format (__printf__,3 ,4 )));int vsprintf (char *buf,const char *fmt,va_list args); +int vsnprintf (char *buf,size_t size,const char *fmt,va_list args); +int vscnprintf (char *buf,size_t size,const char *fmt,va_list args);/* lib/strmhz.c */ char *strmhz (char *buf,unsigned long hz);
lib/vsprintf.c +249 -67
464 lines not on this page · raw message
Signature · 1 line
1.7.3.1
PATCH 2/4 Add safe vsnprintf and snprintf library functions
Hi Simon,
Quoted 11 lines · Simon Glass
From: Sonny Rao <[email protected]>
From: Sonny Rao <[email protected]>
These functions are useful in U-Boot because they allow a graceful failure rather than an unpredictable stack overflow when
printf()buffers are exceeded.Mostly copied from the Linux kernel. I copied vscnprintf and scnprintf so we can change printf and vprintf to use the safe implementation but still return the correct values.
Have you checked for license compatibility? U-Boot is GPLv2+ and (most) of Linux is GPLv2 - You may not be legally permitted to do this
Regards,
Graeme
PATCH 2/4 Add safe vsnprintf and snprintf library functions
Quoted 11 lines · Graeme Russ
Hi Simon,
Quoted 8 lines · Simon Glass
From: Sonny Rao <[email protected]>
From: Sonny Rao <[email protected]>
These functions are useful in U-Boot because they allow a graceful failure rather than an unpredictable stack overflow when
printf()buffers are exceeded.
Quoted 6 lines
Quoted 3 lines
Mostly copied from the Linux kernel. I copied vscnprintf and scnprintf so we can change printf and vprintf to use the safe implementation but still return the correct values.
Have you checked for license compatibility? U-Boot is GPLv2+ and (most) of Linux is GPLv2 - You may not be legally permitted to do this
According to the FSF site, GPLv2 is compatible with GPLv3, see:
http://www.gnu.org/licenses/quick-guide-gplv3.html
So it's fine to distribute them together.
In reality though, this code in U-boot was already copied from the same file in an older version of the kernel. The license (GPLv2 only) hasn't changed on that file, so U-boot is already distributing what is GPLv2 only code alongside GPLv2+ code -- which as I mentioned above is fine.
The code here is derived from a later version of that same file, so I don't believe integrating this patch into U-boot actually changes anything with respect to licensing of this code.
Sonny
PATCH 2/4 Add safe vsnprintf and snprintf library functions
Hi Sonny,
Quoted 16 lines · Sonny Rao
Quoted 15 lines · Graeme Russ
Hi Simon,
Quoted 11 lines · Simon Glass
From: Sonny Rao <[email protected]>
From: Sonny Rao <[email protected]>
These functions are useful in U-Boot because they allow a graceful failure rather than an unpredictable stack overflow when
printf()buffers are exceeded.Mostly copied from the Linux kernel. I copied vscnprintf and scnprintf so we can change printf and vprintf to use the safe implementation but still return the correct values.
Quoted 7 lines
Quoted 2 lines
Have you checked for license compatibility? U-Boot is GPLv2+ and (most) of Linux is GPLv2 - You may not be legally permitted to do this
According to the FSF site, GPLv2 is compatible with GPLv3, see:
http://www.gnu.org/licenses/quick-guide-gplv3.htmlSo it's fine to distribute them together.
Not so fast:
"GPLv2 is compatible with GPLv3 if the program allows you to choose "any later version" of the GPL, which is the case for most software released under this license"
'most', not 'all'
The key phrase is "any later version" - If this is not in the GPLv2 license text for the code your copying, you cannot license the derivative work under GPLv3 (or GPLv2+)
Quoted 5 lines
In reality though, this code in U-boot was already copied from the same file in an older version of the kernel. The license (GPLv2 only) hasn't changed on that file, so U-boot is already distributing what is GPLv2 only code alongside GPLv2+ code -- which as I mentioned above is fine.
As long as you are not incorporating GPLv2 code into a file licensed under GPLv2+ and distributing the result as GPLv2+ or GPLv3.
Quoted 3 lines
The code here is derived from a later version of that same file, so I don't believe integrating this patch into U-boot actually changes anything with respect to licensing of this code.
I think U-Boot will have great difficulty going past GPLv2 due to the large volume of Linus code already in U-Boot - We would need to either get the original code relicensed GPLv2+ or rewrite it
And from the COPYING file in the Linux source:
Also note that the only valid version of the GPL as far as the kernel is concerned is _this_ particular version of the license (ie v2, not v2.2 or v3.x or whatever), unless explicitly otherwise stated.
and linux/lib/vsprintf.c:
/*
* linux/lib/vsprintf.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ /*
* Wirzenius wrote this portably, Torvalds fucked it up :-) */
/*
* Fri Jul 13 2001 Crutcher Dunnavant <[email protected]>
* - changed to provide snprintf and vsnprintf functions
* So Feb 1 16:51:32 CET 2004 Juergen Quade <[email protected]>
* - scnprintf and vscnprintf
*/
No 'any later version'
Now U-Boot COPYING has:
U-Boot is Free Software. It is copyrighted by Wolfgang Denk and many others who contributed code (see the actual source code for details). You can redistribute U-Boot and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. Most of it can also be distributed,
-----------------------------------
at your option, under any later version of the GNU General Public
-----------------------------------------------------------------
License -- see individual files for exceptions.
-----------------------------------------------
So U-Boot is also GPLv2, but parts (like Linux) are GPLv2+
My point was there is a long term 'vision' for U-Boot to go GPLv3, and part of that vision is to reject any future GPLv2 only licensed code submitted. If we want the vision to be realised, I think we need to look at how we build new GPLv2+ code in new files rather than tying new code into GPLv2 only files which may, potentially, lock that code down. Although as the writer and copyright holder of a modification you may be free to move it over at a later date anyway - I don't know, and I think that's in the 'ask a lawyer' territory.
So yes, you are right - In terms of license compliance, we are OK as U-Boot is currently GPLv2 - In terms of U-Boot going to GPLv3, we are digging a bigger hole :)
Regards,
Graeme
PATCH 2/4 Add safe vsnprintf and snprintf library functions
Quoted 33 lines · Graeme Russ
Hi Sonny,
Quoted 16 lines · Sonny Rao
Quoted 15 lines · Graeme Russ
Hi Simon,
Quoted 11 lines · Simon Glass
From: Sonny Rao <[email protected]>
From: Sonny Rao <[email protected]>
These functions are useful in U-Boot because they allow a graceful failure rather than an unpredictable stack overflow when
printf()buffers are exceeded.Mostly copied from the Linux kernel. I copied vscnprintf and scnprintf so we can change printf and vprintf to use the safe implementation but still return the correct values.
Quoted 7 lines
Quoted 2 lines
Have you checked for license compatibility? U-Boot is GPLv2+ and (most) of Linux is GPLv2 - You may not be legally permitted to do this
According to the FSF site, ?GPLv2 is compatible with GPLv3, see:
http://www.gnu.org/licenses/quick-guide-gplv3.htmlSo it's fine to distribute them together.
Not so fast:
"GPLv2 is compatible with GPLv3 if the program allows you to choose "any later version" of the GPL, which is the case for most software released under this license"
Quoted 5 lines
'most', not 'all'
The key phrase is "any later version" - If this is not in the GPLv2 license text for the code your copying, you cannot license the derivative work under GPLv3 (or GPLv2+)
I'm a bit confused here... I was talking about distribution, not re-licensing. I'm certainly not saying U-boot should be trying to re-license GPLv2 only code. But the fact is that U-boot is already contains GPLv2 and GPLv2+ code and it is being distributed together.
Quoted 9 lines
Quoted 5 lines
In reality though, this code in U-boot was already copied from the same file in an older version of the kernel. ?The license (GPLv2 only) hasn't changed on that file, so U-boot is already distributing what is GPLv2 only code alongside GPLv2+ code -- which as I mentioned above is fine.
As long as you are not incorporating GPLv2 code into a file licensed under GPLv2+ and distributing the result as GPLv2+ or GPLv3.
My argument is that this code in U-boot was already GPLv2 only since it came from a GPLv2 only file in the kernel. I don't think that we're applying GPLv2 code into a file licensed under GPLv2+. Perhaps we could add an explicit comment stating that the code in lib/vsprintf.c is GPLv2 only so nobody gets the wrong idea.
Quoted 27 lines
Quoted 3 lines
The code here is derived from a later version of that same file, so I don't believe integrating this patch into U-boot actually changes anything with respect to licensing of this code.
I think U-Boot will have great difficulty going past GPLv2 due to the large volume of Linus code already in U-Boot - We would need to either get the original code relicensed GPLv2+ or rewrite it
And from the COPYING file in the Linux source:
Also note that the only valid version of the GPL as far as the kernel is concerned is _this_ particular version of the license (ie v2, not v2.2 or v3.x or whatever), unless explicitly otherwise stated.
and
linux/lib/vsprintf.c:/*
?* ?linux/lib/vsprintf.c
?*
?* ?Copyright (C) 1991, 1992 ?Linus Torvalds
?*//*
vsprintf.c-- Lars Wirzenius & Linus Torvalds. */ /*
?* Wirzenius wrote this portably, Torvalds fucked it up :-) ?*/
Quoted 8 lines
/*
?* Fri Jul 13 2001 Crutcher Dunnavant <[email protected]> ?* - changed to provide snprintf and vsnprintf functions
?* So Feb ?1 16:51:32 CET 2004 Juergen Quade <[email protected]> ?* - scnprintf and vscnprintf
?*/No 'any later version'
Yes, as I said before, this code is definitely GPLv2 only. I don't think we're disagreeing here.
Quoted 24 lines
Now U-Boot COPYING has:
U-Boot is Free Software. ?It is copyrighted by Wolfgang Denk and many others who contributed code (see the actual source code for details). ?You can redistribute U-Boot and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. ?Most of it can also be distributed, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ----------------------------------- at your option, under any later version of the GNU General Public
-----------------------------------------------------------------
License -- see individual files for exceptions.
-----------------------------------------------So U-Boot is also GPLv2, but parts (like Linux) are GPLv2+
My point was there is a long term 'vision' for U-Boot to go GPLv3, and part of that vision is to reject any future GPLv2 only licensed code submitted. If we want the vision to be realised, I think we need to look at how we build new GPLv2+ code in new files rather than tying new code into GPLv2 only files which may, potentially, lock that code down. Although as the writer and copyright holder of a modification you may be free to move it over at a later date anyway - I don't know, and I think that's in the 'ask a lawyer' territory.
Quoted 3 lines
So yes, you are right - In terms of license compliance, we are OK as U-Boot is currently GPLv2 - In terms of U-Boot going to GPLv3, we are digging a bigger hole :)
Ok, then that's up to the U-boot community to decide if they wish to remove all GPLv2 only code, but I think that's a separate issue from what you originally brought up. I think we're in agreement that there aren't any licensing considerations with respect to maintaining the existing license which is GPLv2 only for lib/vsprintf.c.
Sonny
PATCH 2/4 Add safe vsnprintf and snprintf library functions
Hi Sonny,
Quoted 3 lines · Sonny Rao
Quoted 2 lines · Graeme Russ
Hi Sonny,
[snip]
Quoted 9 lines
Quoted 3 lines
So yes, you are right - In terms of license compliance, we are OK as U-Boot is currently GPLv2 - In terms of U-Boot going to GPLv3, we are digging a bigger hole :)
Ok, then that's up to the U-boot community to decide if they wish to remove all GPLv2 only code, but I think that's a separate issue from what you originally brought up. I think we're in agreement that there aren't any licensing considerations with respect to maintaining the existing license which is GPLv2 only for
lib/vsprintf.c.
Agree 100%
Regards,
Graeme
PATCH 3/4 Make printf and vprintf safe from buffer overruns
In reply to Simon GlassFrom: Sonny Rao <[email protected]>
From: Sonny Rao <[email protected]>
utilize the added vscnprintf functions to avoid buffer overruns The implementation is fairly dumb in that it doesn't detect that the buffer is too small, but at least will not cause crashes.
--- common/console.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
common/console.c +5 -5
@@ -212,7 +212,7 @@ int serial_printf(const char *fmt, ...)/* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i =vsprintf (printbuffer, fmt, args); + i =vscnprintf (printbuffer,CONFIG_SYS_PBSIZE , fmt, args);va_end (args);serial_puts (printbuffer);
@@ -281,7 +281,7 @@ int fprintf(int file, const char *fmt, ...)/* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i =vsprintf (printbuffer, fmt, args); + i =vscnprintf (printbuffer,CONFIG_SYS_PBSIZE , fmt, args);va_end (args);/* Send to desired file */
@@ -376,7 +376,7 @@ int printf(const char *fmt, ...)/* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i =vsprintf (printbuffer, fmt, args); + i =vscnprintf (printbuffer,CONFIG_SYS_PBSIZE , fmt, args);va_end (args);/* Print the string */
@@ -392,7 +392,7 @@ int vprintf(const char *fmt, va_list args)/* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i =vsprintf (printbuffer, fmt, args); + i =vscnprintf (printbuffer,CONFIG_SYS_PBSIZE , fmt, args);/* Print the string */ puts (printbuffer);
@@ -459,7 +459,7 @@ inline void dbg(const char *fmt, ...)/* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i =vsprintf (printbuffer, fmt, args); + i =vsnprintf (printbuffer,CONFIG_SYS_PBSIZE , fmt, args);va_end (args); if ((screen + sizeof(screen) - 1 - cursor)
Signature · 1 line
1.7.3.1
PATCH 3/4 Make printf and vprintf safe from buffer overruns
Quoted 4 lines · Simon Glass
From: Sonny Rao <[email protected]>
From: Sonny Rao <[email protected]>
Quoted 8 lines
utilize the added vscnprintf functions to avoid buffer overruns The implementation is fairly dumb in that it doesn't detect that the buffer is too small, but at least will not cause crashes.
Signed-off-by Simon Glass <[email protected]>---
common/console.c| 10 +++++-----1 files changed, 5 insertions(+), 5 deletions(-)
If these are from Sonny, they really should have a Signed-off-by from him.
- k
PATCH 3/4 Make printf and vprintf safe from buffer overruns
Hi Kumar,
Quoted 11 lines · Kumar Gala
Quoted 8 lines · Simon Glass
From: Sonny Rao <[email protected]>
From: Sonny Rao <[email protected]>
utilize the added vscnprintf functions to avoid buffer overruns The implementation is fairly dumb in that it doesn't detect that the buffer is too small, but at least will not cause crashes.
Quoted 7 lines
Quoted 4 lines
Signed-off-by Simon Glass <[email protected]>---
common/console.c| ? 10 +++++-----1 files changed, 5 insertions(+), 5 deletions(-)If these are from Sonny, they really should have a Signed-off-by from him.
OK will fix that with next version thanks. The commit in my tree says Sonny but perhaps git format-patch --signoff is not doing what I expect.
Regards,
Simon
Quoted 2 lines
- k
PATCH 3/4 Make printf and vprintf safe from buffer overruns
In reply to Simon Glasscommon/console.c int serial_printf(const char *fmt, ...) · line 215
Quoted 8 lines · On Friday, September 23, 2011 13:38:51 Simon Glass wrote:
common/console.c +1
-1@@ -212,7 +212,7 @@ int serial_printf(const char *fmt, ...)/* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i =vsprintf (printbuffer, fmt, args); + i =vscnprintf (printbuffer,CONFIG_SYS_PBSIZE , fmt, args);
i think sizeof(printbuffer) would be better. same goes for all the other changes here.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110923/a97d9d44/attachment.pgp
PATCH 3/4 Make printf and vprintf safe from buffer overruns
Hi Mike,
Quoted 14 lines · Mike Frysinger
Quoted 8 lines · On Friday, September 23, 2011 13:38:51 Simon Glass wrote:
common/console.c +0
-0@@ -212,7 +212,7 @@ int serial_printf(const char *fmt, ...)? ? ? /* For this to work, printbuffer must be larger than ? ? ? ?* anything we ever want to print.
? ? ? ?*/
- ? ? i =vsprintf(printbuffer, fmt, args);
+ ? ? i =vscnprintf(printbuffer, CONFIG_SYS_PBSIZE, fmt, args);i think sizeof(printbuffer) would be better. ?same goes for all the other changes here.
-mike
Yes, indeed. Could we go as far as removing CONFIG_SYS_PBSIZE, and just use a standard value?
Regards,
Simon
PATCH 3/4 Make printf and vprintf safe from buffer overruns
Quoted 15 lines · On Friday, September 23, 2011 16:41:50 Simon Glass wrote:
Quoted 13 lines · Mike Frysinger
common/console.c int serial_printf(const char *fmt, ...) · line 215
Quoted 8 lines · On Friday, September 23, 2011 13:38:51 Simon Glass wrote:
common/console.c +1
-1@@ -212,7 +212,7 @@ int serial_printf(const char *fmt, ...)/* For this to work, printbuffer must be larger than * anything we ever want to print. */ - i =vsprintf (printbuffer, fmt, args); + i =vscnprintf (printbuffer,CONFIG_SYS_PBSIZE , fmt, args);i think sizeof(printbuffer) would be better. same goes for all the other changes here.
-mike
Quoted 2 lines
Yes, indeed. Could we go as far as removing
CONFIG_SYS_PBSIZE, and just use a standard value?
in the context of I/O funcs, CONFIG_SYS_PBSIZE is the current standard -mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110923/342d5445/attachment.pgp
PATCH 3/4 Make printf and vprintf safe from buffer overruns
Hi Mike,
Quoted 16 lines · Mike Frysinger
Quoted 15 lines · On Friday, September 23, 2011 16:41:50 Simon Glass wrote:
Quoted 13 lines · Mike Frysinger
Quoted 8 lines · On Friday, September 23, 2011 13:38:51 Simon Glass wrote:
common/console.c +0
-0@@ -212,7 +212,7 @@ int serial_printf(const char *fmt, ...)? ? ? /* For this to work, printbuffer must be larger than ? ? ? ?* anything we ever want to print.
? ? ? ?*/
- ? ? i =vsprintf(printbuffer, fmt, args);
+ ? ? i =vscnprintf(printbuffer, CONFIG_SYS_PBSIZE, fmt, args);i think sizeof(printbuffer) would be better. ?same goes for all the other changes here.
-mike
Quoted 6 lines
Quoted 2 lines
Yes, indeed. Could we go as far as removing
CONFIG_SYS_PBSIZE, and just use a standard value?in the context of I/O funcs,
CONFIG_SYS_PBSIZEis the current standard -mike
OK - is there a reason why boards can redefine this? Many many boards do. It seems like something that should just be given a sensible value.
Regards,
Simon
PATCH 3/4 Make printf and vprintf safe from buffer overruns
Dear Simon Glass,
Quoted 6 lines · In message <CAPnjgZ2D8MYS7wHMFUnzVhXK_tcmv7GayJyEormkPDNA78p7JQ@mail.gmail.com>…
Quoted 2 lines
in the context of I/O funcs,
CONFIG_SYS_PBSIZEis the current standardOK - is there a reason why boards can redefine this? Many many boards do. It seems like something that should just be given a sensible value.
Indeed - that's exactly what the board specific definitions are supposed to do.
Best regards,
Wolfgang Denk
Signature · 7 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Es ist offensichtlich, dass das menschliche Gehirn wie ein Computer
funktioniert. Da es keine dummen Computer gibt, gibt es also auch
keine dummen Menschen. Nur ein paar Leute, die unter DOS laufen.
-- <unbekannt>PATCH 3/4 Make printf and vprintf safe from buffer overruns
In reply to Simon GlassDear Simon Glass,
Quoted 3 lines · In message <CAPnjgZ0-8wU4Hj3pdmfNMWnj4EPUmQ69U_UARaRt5CbqQv0Ofg@mail.gmail.com>…
Yes, indeed. Could we go as far as removing
CONFIG_SYS_PBSIZE, and just use a standard value?
If you can find one that fits for all boards? Keep in mind that printf() gets used before relocation, when available stack space may be _very_ limited.
Best regards,
Wolfgang Denk
Signature · 6 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de "And it should be the law: If you use the word `paradigm' without knowing what the dictionary says it means, you go to jail. No exceptions." - David Jones @ Megatest Corporation
PATCH 3/4 Make printf and vprintf safe from buffer overruns
HI Wolfgang,
Quoted 10 lines · Wolfgang Denk
Dear Simon Glass,
Quoted 3 lines · In message <CAPnjgZ0-8wU4Hj3pdmfNMWnj4EPUmQ69U_UARaRt5CbqQv0Ofg@mail.gmail.com>…
Yes, indeed. Could we go as far as removing
CONFIG_SYS_PBSIZE, and just use a standard value?If you can find one that fits for all boards? ?Keep in mind that
printf()gets used before relocation, when available stack space may be _very_ limited.
Yes that is a problem. Perhaps we could changes things so that this CONFIG really only matters prior to relocation (see other thread with Albert) and we could just choose a suitable small value like 256, which seems to be the minimum for most boards.
Regards,
Simon
Quoted 13 lines
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, ? ? MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de "And it should be the law: If you use ?the ?word ?`paradigm' ?without knowing ?what ?the ?dictionary ?says ?it ?means, ?you ?go to jail. No exceptions." ? ? ? ? ? ? ? ? ? ? - David Jones @ Megatest Corporation
PATCH 3/4 Make printf and vprintf safe from buffer overruns
Dear Simon Glass,
Quoted 9 lines · In message <CAPnjgZ1Q89Ew2Be2QcjoWF3Nyb+sJ-SxfFunZturMwdLxBc_Wg@mail.gmail.com>…
Quoted 4 lines
If you can find one that fits for all boards? =A0Keep in mind that
printf()gets used before relocation, when available stack space may be _very_ limited.Yes that is a problem. Perhaps we could changes things so that this CONFIG really only matters prior to relocation (see other thread with Albert) and we could just choose a suitable small value like 256, which seems to be the minimum for most boards.
You are probably addressing a non-issue. How many related bug reports can you find in the last decade or so?
Best regards,
Wolfgang Denk
Signature · 5 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de All your people must learn before you can reach for the stars. -- Kirk, "The Gamesters of Triskelion", stardate 3259.2
PATCH 3/4 Make printf and vprintf safe from buffer overruns
Hi Wolfgang,
Quoted 8 lines · Wolfgang Denk
Dear Simon Glass,
Quoted 5 lines · In message <CAPnjgZ1Q89Ew2Be2QcjoWF3Nyb+sJ-SxfFunZturMwdLxBc_Wg@mail.gmail.com>…
Quoted 4 lines
If you can find one that fits for all boards? =A0Keep in mind that
printf()gets used before relocation, when available stack space may be _very_ limited.
Quoted 8 lines
Quoted 4 lines
Yes that is a problem. Perhaps we could changes things so that this CONFIG really only matters prior to relocation (see other thread with Albert) and we could just choose a suitable small value like 256, which seems to be the minimum for most boards.
You are probably addressing a non-issue. ?How many related bug reports can you find in the last decade or so?
Yes probably, it isn't important and is off-topic from my patch anyway.
Regards,
Simon
Quoted 11 lines
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, ? ? MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de All your people must learn before you can reach for the stars. ? ? ? ?-- Kirk, "The Gamesters of Triskelion", stardate 3259.2
PATCH 4/4 Use snprintf() in network code
In reply to Simon GlassThis tidies up network code to use snprintf() in most cases instead of sprintf(). A few functions remain as they require header file changes.
--- net/eth.c | 10 +++++++--- net/net.c | 15 ++++++++++----- net/nfs.c | 3 ++- net/tftp.c | 3 ++- 4 files changed, 21 insertions(+), 10 deletions(-)
net/eth.c +7 -3
@@ -49,7 +49,7 @@ int eth_setenv_enetaddr(char *name, const uchar *enetaddr) {char buf[20 ]; -sprintf (buf,"%pM" , enetaddr); +snprintf (buf,sizeof (buf),"%pM" , enetaddr);return setenv (name, buf); }
@@ -58,7 +58,9 @@ int eth_getenv_enetaddr_by_index(const char *base_name, int index, uchar *enetaddr) {char enetvar[32 ]; -sprintf (enetvar, index ?"%s%daddr" :"%saddr" , base_name, index); + +snprintf (enetvar,sizeof (enetvar), index ?"%s%daddr" :"%saddr" , + base_name, index);return eth_getenv_enetaddr (enetvar, enetaddr); }
@@ -68,7 +70,9 @@ static int eth_mac_skip(int index) {char enetvar[15 ];char *skip_state; -sprintf (enetvar, index ?"eth%dmacskip" :"ethmacskip" , index); + +snprintf (enetvar,sizeof (enetvar), + index ?"eth%dmacskip" :"ethmacskip" , index);return ((skip_state =getenv (enetvar)) !=NULL ); }
net/net.c +10 -5
@@ -573,10 +573,12 @@ restart:printf ("Bytes transferred = %ld (%lx hex)\n" , NetBootFileXferSize, NetBootFileXferSize); -sprintf (buf,"%lX" , NetBootFileXferSize); +snprintf (buf,sizeof (buf),"%lX" , + NetBootFileXferSize);setenv ("filesize" , buf); -sprintf (buf,"%lX" , (unsigned long )load_addr); +snprintf (buf,sizeof (buf),"%lX" , + (unsigned long )load_addr);setenv ("fileaddr" , buf); }eth_halt ();
@@ -950,7 +952,8 @@ int CDPSendTrigger(void)#ifdef CONFIG_CDP_DEVICE_ID *s++ =htons (CDP_DEVICE_ID_TLV ); *s++ =htons (CONFIG_CDP_DEVICE_ID ); -sprintf (buf,CONFIG_CDP_DEVICE_ID_PREFIX "%pm" , NetOurEther); +snprintf (buf,sizeof (buf),CONFIG_CDP_DEVICE_ID_PREFIX "%pm" , + NetOurEther);memcpy ((uchar *)s, buf,16 ); s +=16 /2 ;#endif
@@ -958,7 +961,7 @@ int CDPSendTrigger(void)#ifdef CONFIG_CDP_PORT_ID *s++ =htons (CDP_PORT_ID_TLV );memset (buf,0 ,sizeof (buf)); -sprintf (buf,CONFIG_CDP_PORT_ID ,eth_get_dev_index ()); +snprintf (buf,sizeof (buf),CONFIG_CDP_PORT_ID ,eth_get_dev_index ()); len =strlen (buf);if (len &1 )/* make it even */ len++;
@@ -1516,7 +1519,9 @@ NetReceive(volatile uchar *inpkt, int len)#ifdef CONFIG_KEEP_SERVERADDR if (NetServerIP == NetArpWaitPacketIP) {char buf[20 ]; -sprintf (buf,"%pM" , arp->ar_data); + +snprintf (buf,sizeof (buf),"%pM" , + arp->ar_data);setenv ("serveraddr" , buf); }#endif
net/nfs.c +2 -1
@@ -688,7 +688,8 @@ NfsStart (void) }if (BootFile[0 ] =='\0' ) { - sprintf (default_filename, "/nfsroot/%02lX%02lX%02lX%02lX.img", + snprintf(default_filename, sizeof(default_filename), + "/nfsroot/%02lX%02lX%02lX%02lX.img", NetOurIP & 0xFF, (NetOurIP >> 8) & 0xFF, (NetOurIP >> 16) & 0xFF,
net/tftp.c +2 -1
@@ -591,7 +591,8 @@ TftpStart(void) TftpRemoteIP = NetServerIP;if (BootFile[0 ] =='\0' ) { - sprintf(default_filename, "%02lX%02lX%02lX%02lX.img", + snprintf(default_filename, sizeof(default_filename), + "%02lX%02lX%02lX%02lX.img", NetOurIP & 0xFF, (NetOurIP >> 8) & 0xFF, (NetOurIP >> 16) & 0xFF,
Signature · 1 line
1.7.3.1
PATCH 4/4 Use snprintf() in network code
Quoted 2 lines · On Friday, September 23, 2011 13:38:52 Simon Glass wrote:
This tidies up network code to use
snprintf()in most cases instead ofsprintf(). A few functions remain as they require header file changes.
NAK to most of these. we pick local sized buffers that are known to not overflow, or require circumstances that aren't really feasible.
3 examples (which are the first 3 changes in this patch) below ...
net/eth.c int eth_setenv_enetaddr(char *name, const uchar *enetaddr) · line 52
Quoted 6 lines
net/eth.c +1
-1char buf[20 ]; -sprintf (buf,"%pM" , enetaddr); +snprintf (buf,sizeof (buf),"%pM" , enetaddr);
a mac address will not take more than 19 bytes. unless the sprintf code is completely busted, but if that's the case, we should fix that instead since it'd be pretty fundamentally screwed.
net/eth.c int eth_getenv_enetaddr_by_index(const char *base_name, int index, · line 63
Quoted 4 lines
net/eth.c +2
-1char enetvar[32 ]; -sprintf (enetvar, index ?"%s%daddr" :"%saddr" , base_name, index); +snprintf (enetvar,sizeof (enetvar), index ?"%s%daddr" :"%saddr" , + base_name, index);
in order for this to overflow, we have to have 1000+ eth devices (maybe more? i'd have to read the code closer)
net/eth.c static int eth_mac_skip(int index) · line 75
Quoted 4 lines
net/eth.c +2
-1char enetvar[15 ]; -sprintf (enetvar, index ?"eth%dmacskip" :"ethmacskip" , index); +snprintf (enetvar,sizeof (enetvar), + index ?"eth%dmacskip" :"ethmacskip" , index);
in order for this to overflow, we have to have 10000+ eth devices
please look at the realistic needs rather than blanket converting to snprintf -mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110923/0dca814e/attachment.pgp
PATCH 4/4 Use snprintf() in network code
Hi Mike,
Quoted 6 lines · Mike Frysinger
Quoted 2 lines · On Friday, September 23, 2011 13:38:52 Simon Glass wrote:
This tidies up network code to use
snprintf()in most cases instead ofsprintf(). A few functions remain as they require header file changes.NAK to most of these. ?we pick local sized buffers that are known to not overflow, or require circumstances that aren't really feasible.
Yes that's why I sent this patch on the end, to see how far this should be taken.
Quoted 6 lines
3 examples (which are the first 3 changes in this patch) below ...
Quoted 3 lines
net/eth.c +0
-0
Quoted 7 lines
Quoted 3 lines
? ? ? char buf[20];
- ? ?sprintf(buf, "%pM", enetaddr);
+ ? ?snprintf(buf, sizeof(buf), "%pM", enetaddr);a mac address will not take more than 19 bytes. ?unless the sprintf code is completely busted, but if that's the case, we should fix that instead since it'd be pretty fundamentally screwed.
OK (18 bytes?)
Quoted 8 lines
Quoted 5 lines
? ? ? char enetvar[32];
- ? ?sprintf(enetvar, index ? "%s%daddr" : "%saddr", base_name, index);
+ ? ? snprintf(enetvar, sizeof(enetvar), index ? "%s%daddr" : "%saddr",
+ ? ? ? ? ? ? ?base_name, index);in order for this to overflow, we have to have 1000+ eth devices (maybe more? i'd have to read the code closer)
Or base_name could be longer.
Quoted 9 lines
Quoted 5 lines
? ? ? char enetvar[15];
- ? ?sprintf(enetvar, index ? "eth%dmacskip" : "ethmacskip", index);
+ ? ? snprintf(enetvar, sizeof(enetvar),
+ ? ? ? ? ? ? index ? "eth%dmacskip" : "ethmacskip", index);in order for this to overflow, we have to have 10000+ eth devices
please look at the realistic needs rather than blanket converting to snprintf
OK, this is fair enough. There are a couple of functions like ip_to_string() which don't get passed a length. I would prefer to see this done, so we can use snprintf() or assert() since the code then becomes more robust. But there are no bugs there at present. Thoughts?
Regards,
Simon
Quoted 2 lines
-mike
PATCH 4/4 Use snprintf() in network code
Quoted 13 lines · On Friday, September 23, 2011 14:30:09 Simon Glass wrote:
Quoted 11 lines · Mike Frysinger
net/eth.c int eth_setenv_enetaddr(char *name, const uchar *enetaddr) · line 52
Quoted 6 lines · On Friday, September 23, 2011 13:38:52 Simon Glass wrote:
net/eth.c +1
-1char buf[20 ]; -sprintf (buf,"%pM" , enetaddr); +snprintf (buf,sizeof (buf),"%pM" , enetaddr);a mac address will not take more than 19 bytes. unless the sprintf code is completely busted, but if that's the case, we should fix that instead since it'd be pretty fundamentally screwed.
Quoted 1 line
OK (18 bytes?)
right ... i meant there's 19 available (since 20 makes NUL), and there's no way it should hit that 19 limit.
Quoted 9 lines
Quoted 7 lines
net/eth.c int eth_getenv_enetaddr_by_index(const char *base_name, int index, · line 63
Quoted 4 lines
char enetvar[32];net/eth.c +2
-1-sprintf (enetvar, index ?"%s%daddr" :"%saddr" , base_name, index); +snprintf (enetvar,sizeof (enetvar), index ?"%s%daddr" :"%saddr" , + base_name, index);in order for this to overflow, we have to have 1000+ eth devices (maybe more? i'd have to read the code closer)
Or
base_namecould be longer.
true, but base_name atm is supposed to be "eth" or "usbeth". i would hope we'd be diligent about device naming conventions rather than letting someone slip in "mysuperawesomeboardeth" (although that still wouldn't overflow ;]).
Quoted 7 lines
Quoted 7 lines
net/eth.c static int eth_mac_skip(int index) · line 75
Quoted 4 lines
char enetvar[15];net/eth.c +2
-1-sprintf (enetvar, index ?"eth%dmacskip" :"ethmacskip" , index); +snprintf (enetvar,sizeof (enetvar), + index ?"eth%dmacskip" :"ethmacskip" , index);in order for this to overflow, we have to have 10000+ eth devices
Quoted 7 lines
Quoted 2 lines
please look at the realistic needs rather than blanket converting to snprintf
OK, this is fair enough. There are a couple of functions like
ip_to_string()which don't get passed a length. I would prefer to see this done, so we can usesnprintf()orassert()since the code then becomes more robust. But there are no bugs there at present. Thoughts?
for funcs that do generally handle arbitrary data, i don't mind including len specs, but when we're using known standards, i'd prefer to stick to the smaller/simpler code. this is a thin boot loader that is meant to be fast, and there are plenty of ways to bring down the system otherwise (and i don't think these cases are generally a robustness concern).
don't know if wolfgang has an opinion.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110923/7c5e56f6/attachment.pgp
PATCH 4/4 Use snprintf() in network code
Hi Mike,
Quoted 24 lines · Mike Frysinger
Quoted 13 lines · On Friday, September 23, 2011 14:30:09 Simon Glass wrote:
Quoted 11 lines · Mike Frysinger
Quoted 6 lines · On Friday, September 23, 2011 13:38:52 Simon Glass wrote:
net/eth.c +0
-0? ? ? char buf[20];
- ? ?sprintf(buf, "%pM", enetaddr);
+ ? ?snprintf(buf, sizeof(buf), "%pM", enetaddr);a mac address will not take more than 19 bytes. ?unless the sprintf code is completely busted, but if that's the case, we should fix that instead since it'd be pretty fundamentally screwed.
Quoted 1 line
OK (18 bytes?)
right ... i meant there's 19 available (since 20 makes NUL), and there's no way it should hit that 19 limit.
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
? ? ? char enetvar[32];
- ? ?sprintf(enetvar, index ? "%s%daddr" : "%saddr", base_name, index);
+ ? ? snprintf(enetvar, sizeof(enetvar), index ? "%s%daddr" : "%saddr",
+ ? ? ? ? ? ? ?base_name, index);
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
in order for this to overflow, we have to have 1000+ eth devices (maybe more? i'd have to read the code closer)
Or
base_namecould be longer.true, but
base_nameatm is supposed to be "eth" or "usbeth". ?i would hope we'd be diligent about device naming conventions rather than letting someone slip in "mysuperawesomeboardeth" (although that still wouldn't overflow ;]).
Well here I feel that it is pushing it a bit to have a function that builds a string based on arguments over which it has no control. I suppose an assert(strlen(base_name) < 23) or whatever would do it. But isn't snprintf() better?
Quoted 16 lines
Quoted 8 lines
Quoted 8 lines
Quoted 5 lines
? ? ? char enetvar[15];
- ? ?sprintf(enetvar, index ? "eth%dmacskip" : "ethmacskip", index);
+ ? ? snprintf(enetvar, sizeof(enetvar),
+ ? ? ? ? ? ? index ? "eth%dmacskip" : "ethmacskip", index);in order for this to overflow, we have to have 10000+ eth devices
Quoted 7 lines
Quoted 2 lines
please look at the realistic needs rather than blanket converting to snprintf
OK, this is fair enough. There are a couple of functions like
ip_to_string()which don't get passed a length. I would prefer to see this done, so we can usesnprintf()orassert()since the code then becomes more robust. But there are no bugs there at present. Thoughts?
Quoted 5 lines
for funcs that do generally handle arbitrary data, i don't mind including len specs, but when we're using known standards, i'd prefer to stick to the smaller/simpler code. ?this is a thin boot loader that is meant to be fast, and there are plenty of ways to bring down the system otherwise (and i don't think these cases are generally a robustness concern).
Well that argues towards using assert() in these cases rather than just ignoring them. I'm keen to try to make U-Boot more testable. I do understand it is just a 'thin' boot loader, but it has quite a few features now, and it if breaks, the system won't boot.
I do agree there is a difference between telling devs about a bug / overflow at build/test time and bloating the code in production. Either/or is good with me, but I'm not entirely comfortable with just ignoring these issues and hoping they don't bite us. It's not like we have a test suite to check it.
Quoted 2 lines
don't know if wolfgang has an opinion.
<insert here>
Regards,
Simon
Quoted 2 lines
-mike
cover Buffer overruns in printf
In reply to Simon GlassHi Simon,
Le 23/09/2011 19:38, Simon Glass a ?crit :
Quoted 4 lines
The printf family of functions in U-Boot cannot deal with a situation where the caller provides a buffer which turns out to be too small for the format string. This can result in buffer overflows, stack overflows and other bad behavior.
Indeed overruns can lead to bad behaviors, but in any case, it can never be recovered, because at the root, the problem is that the caller provided inconsistent arguments to printf.
So in essence, you're 'fixing' printf for a design error in printf's caller, instead of fixing the design error.
Amicalement,
Signature · 1 line
Albert.
cover Buffer overruns in printf
Hi Albert,
Quoted 11 lines · Albert ARIBAUD
Hi Simon,
Le 23/09/2011 19:38, Simon Glass a ?crit :
Quoted 7 lines
The printf family of functions in U-Boot cannot deal with a situation where
the caller provides a buffer which turns out to be too small for the format
string. This can result in buffer overflows, stack overflows and other bad behavior.
Quoted 3 lines
Indeed overruns can lead to bad behaviors, but in any case, it can never be recovered, because at the root, the problem is that the caller provided inconsistent arguments to printf.
Recovery is one thing, but I would settle for just not crashing, which is the purpose of this patch. We could also easily WARN if that were considered appropriate here.
Quoted 3 lines
So in essence, you're 'fixing' printf for a design error in printf's caller, instead of fixing the design error.
Well, the nature of a function is that it cannot know what arguments might be passed to it. It can only assert(), limit check, etc. A limit check is what this patch aims to add.
Regards,
Simon
Quoted 5 lines
Amicalement,
--
Albert.
cover Buffer overruns in printf
Le 23/09/2011 22:46, Simon Glass a ?crit :
Quoted 24 lines
Hi Albert,
Quoted 11 lines · Albert ARIBAUD
Hi Simon,
Le 23/09/2011 19:38, Simon Glass a ?crit :
Quoted 7 lines
The printf family of functions in U-Boot cannot deal with a situation where
the caller provides a buffer which turns out to be too small for the format
string. This can result in buffer overflows, stack overflows and other bad behavior.Quoted 3 lines
Indeed overruns can lead to bad behaviors, but in any case, it can never be recovered, because at the root, the problem is that the caller provided inconsistent arguments to printf.
Recovery is one thing, but I would settle for just not crashing, which is the purpose of this patch. We could also easily WARN if that were considered appropriate here.
Quoted 1 line
Quoted 6 lines
Quoted 2 lines
So in essence, you're 'fixing' printf for a design error in printf's caller, instead of fixing the design error.
Well, the nature of a function is that it cannot know what arguments might be passed to it. It can only
assert(), limit check, etc. A limit check is what this patch aims to add.
I do agree that as a rule, a function should check its arguments, but as any rule, this one has understated assumptions. Here, one assumption is that calls to the functions cannot be made compliant, and therefore it falls to the function to ensure this compliance; and another one is that the function can actually check this conformance.
The first assumption is correct in an OS or general-purpose library where the number of callers is virtually unlimited and there is no way to make sure all calls are conforming.
In U-Boot however, the number of callers is bound and known (unless you're thinking of standalone U-Boot apps, but I don't see this as a use case so frequent that it warrants a 'fix')
The second assumption is false by nature for printf(), which simply cannot check its input buffer (OTOH *nprintf() does, and it is its job).
Besides, there *is* a sub-family of printf functions which are dedicated to the case where buffers provided may be too small for the print output -- meaning that the issue is known and an easy fix exists if cropping the output is allowable.
So basically the choice is between:
- adding code to the printf() family to try and fix an issue that it is fundamentally unable to properly fix, and for which a solution exists, or
- grepping and fixing calls to *sprintf() in U-Boot that do not respect the known contraints of printf(), by resizing the buffer or calling *snprintf() instead.
I am definitely not in favor of the first option concerning U-Boot.
Quoted 2 lines
Regards,
Simon
Amicalement,
Signature · 1 line
Albert.
cover Buffer overruns in printf
Hi Albert,
Quoted 37 lines · Albert ARIBAUD
Le 23/09/2011 22:46, Simon Glass a ?crit :
Quoted 28 lines
Hi Albert,
Quoted 13 lines · On Fri, Sep 23, 2011 at 1:40 PM, Albert ARIBAUD <[email protected]>…
Hi Simon,
Le 23/09/2011 19:38, Simon Glass a ?crit :
Quoted 8 lines
The printf family of functions in U-Boot cannot deal with a situation where
the caller provides a buffer which turns out to be too small for the format
string. This can result in buffer overflows, stack overflows and other bad
behavior.Quoted 4 lines
Indeed overruns can lead to bad behaviors, but in any case, it can never be
recovered, because at the root, the problem is that the caller provided inconsistent arguments to printf.Recovery is one thing, but I would settle for just not crashing, which is the purpose of this patch. We could also easily WARN if that were considered appropriate here.
Quoted 1 line
Quoted 7 lines
Quoted 3 lines
So in essence, you're 'fixing' printf for a design error in printf's caller,
instead of fixing the design error.Well, the nature of a function is that it cannot know what arguments might be passed to it. It can only
assert(), limit check, etc. A limit check is what this patch aims to add.
Quoted 5 lines
I do agree that as a rule, a function should check its arguments, but as any rule, this one has understated assumptions. Here, one assumption is that calls to the functions cannot be made compliant, and therefore it falls to the function to ensure this compliance; and another one is that the function can actually check this conformance.
There is also the issue of programmer error, or unexpected situations, and graceful failure in these cases. We want to avoid hard-to-find memory/stack corruption bugs if the cost of doing so is moderate.
Quoted 8 lines
The first assumption is correct in an OS or general-purpose library where the number of callers is virtually unlimited and there is no way to make sure all calls are conforming.
In U-Boot however, the number of callers is bound and known (unless you're thinking of standalone U-Boot apps, but I don't see this as a use case so frequent that it warrants a 'fix')
Yes, and one can inspect each call and decide if the nprint() variants are preferable in each case.
Quoted 8 lines
The second assumption is false by nature for
printf(), which simply cannot check its input buffer (OTOH*nprintf()does, and it is its job).Besides, there *is* a sub-family of printf functions which are dedicated to the case where buffers provided may be too small for the print output -- meaning that the issue is known and an easy fix exists if cropping the output is allowable.
Yes, or even if cropping is not allowed, we might expect a nice error, rather than a crash sometime later when the stack corruption or data space overwriting causes problems.
Quoted 11 lines
So basically the choice is between:
- adding code to the
printf()family to try and fix an issue that it is fundamentally unable to properly fix, and for which a solution exists, or- grepping and fixing calls to
*sprintf()in U-Boot that do not respect the known contraints ofprintf(), by resizing the buffer or calling*snprintf()instead.I am definitely not in favor of the first option concerning U-Boot.
Sounds fine to me. So I think we need the nprintf() variants in there, but the message is not to use them willy nilly. Going back to my patch series, 3/4 is ok, but 4/4 mostly crosses the line. Do I have that right?
By the way, printf() ends up calling the same code, but without limit checking in place. The alternative is to duplicate all the format string processing code (a limit-checking version and an unchecked version) which would be worse.
Quoted 4 lines
Amicalement,
--
Albert.
Regards,
Simon
cover Buffer overruns in printf
Le 24/09/2011 16:00, Simon Glass a ?crit :
Quoted 9 lines
Quoted 9 lines
So basically the choice is between:
- adding code to the
printf()family to try and fix an issue that it is fundamentally unable to properly fix, and for which a solution exists, or- grepping and fixing calls to
*sprintf()in U-Boot that do not respect the known contraints ofprintf(), by resizing the buffer or calling*snprintf()instead.
Quoted 6 lines
Quoted 1 line
I am definitely not in favor of the first option concerning U-Boot.
Sounds fine to me. So I think we need the
nprintf()variants in there, but the message is not to use them willy nilly. Going back to my patch series, 3/4 is ok, but 4/4 mostly crosses the line. Do I have that right?
It is the exact opposite for me : 3/4 makes all printf functions work like some kind of *nprintf(), while 4/4 is about the network code switching to *nprintf() for safety, so 3/4 would be nak and 4/4 ack as far as I am concerned.
Basically, printf family functions which do not have the 'n' are *know* by all -- experienced enough :) -- programmers to be *unsafe* (but to require less from the caller) and it should remain so: no programmer should ever encounter an implementation of printf that pretends to be even somewhat safe, because it might bite him/her elsewhere, in another project based on another C library where printf is just the beartrap it usually is.
IOW, programmers already have assumptions about *printf(), including how to deal with length limitations and what happens if you don't, and it is best that these assumption remain true whatever project they work with.
Quoted 4 lines
By the way,
printf()ends up calling the same code, but without limit checking in place. The alternative is to duplicate all the format string processing code (a limit-checking version and an unchecked version) which would be worse.
I don't intend to dictate the way things can be implemented, so the degree of code reuse is an open question as far as I am concerned. I am only voicing my opinion that *printf() APIs and their contracts should remain identical across all implementations of *printf(), and thus that providing *nprintf() where they don't exist is commandable, but hardening printf() is not, since you basically cannot do it without somewhat departing from the de facto standard.
Quoted 2 lines
Regards,
Simon
Amicalement,
Signature · 1 line
Albert.
cover Buffer overruns in printf
Hi Albert,
Quoted 32 lines · Albert ARIBAUD
Le 24/09/2011 16:00, Simon Glass a ?crit :
Quoted 11 lines
Quoted 11 lines
So basically the choice is between:
- adding code to the
printf()family to try and fix an issue that it is fundamentally unable to properly fix, and for which a solution exists, or- grepping and fixing calls to
*sprintf()in U-Boot that do not respect the
known contraints ofprintf(), by resizing the buffer or calling*snprintf()
instead.Quoted 6 lines
Quoted 1 line
I am definitely not in favor of the first option concerning U-Boot.
Sounds fine to me. So I think we need the
nprintf()variants in there, but the message is not to use them willy nilly. Going back to my patch series, 3/4 is ok, but 4/4 mostly crosses the line. Do I have that right?It is the exact opposite for me : 3/4 makes all printf functions work like some kind of
*nprintf(), while 4/4 is about the network code switching to*nprintf()for safety, so 3/4 would be nak and 4/4 ack as far as I am concerned.Basically, printf family functions which do not have the 'n' are *know* by all -- experienced enough :) -- programmers to be *unsafe* (but to require less from the caller) and it should remain so: no programmer should ever encounter an implementation of printf that pretends to be even somewhat safe, because it might bite him/her elsewhere, in another project based on another C library where printf is just the beartrap it usually is.
Quoted 3 lines
IOW, programmers already have assumptions about
*printf(), including how to deal with length limitations and what happens if you don't, and it is best that these assumption remain true whatever project they work with.
I don't quite understand this. You are saying that we shouldn't modify the existing printf(), serial_printf() etc. so live within the buffer they use? If I call printf() and my resulting string is too long for the library then I would much prefer to get truncated output than have to hunt for a wierd crash.
It sounds like you are asking for a new printf(), serial_printf() which provides the facility of limiting the output to n characters, and leave these ones alone. But these functions are not passed a buffer - they use their own and they set the site of it. So I think they should be responsible for enforcing that size.
If you are asking for a new set of functions - nprintf(), serial_nprintf(), etc. then I wonder how you can pass the 'n' but not the actual buffer. In my mind you should not do one without the other.
So please can you clarify?
Quoted 6 lines
Quoted 5 lines
By the way,
printf()ends up calling the same code, but without limit checking in place. The alternative is to duplicate all the format string processing code (a limit-checking version and an unchecked version) which would be worse.
Quoted 7 lines
I don't intend to dictate the way things can be implemented, so the degree of code reuse is an open question as far as I am concerned. I am only voicing my opinion that
*printf()APIs and their contracts should remain identical across all implementations of*printf(), and thus that providing*nprintf()where they don't exist is commandable, but hardeningprintf()is not, since you basically cannot do it without somewhat departing from the de facto standard.
OK fair enough. People are used to printf() just working, no matter what the size. I haven't looked at the implementation but I suspect when the buffer fills it outputs it and starts the buffer again .In any case you don't have to worry about it with the GNU C library.
We probably don't need to go that far in U-Boot, but some simple checking would avoid a nasty surprise for the user. It is obvious from the result that something is truncated, and we can WARN if that helps.
Regards,
Simon
Quoted 8 lines
Quoted 3 lines
Regards,
SimonAmicalement,
--
Albert.
cover Buffer overruns in printf
Hi Simon,
Le 25/09/2011 16:50, Simon Glass a ?crit :
Quoted 11 lines
Quoted 10 lines
Basically, printf family functions which do not have the 'n' are *know* by all -- experienced enough :) -- programmers to be *unsafe* (but to require less from the caller) and it should remain so: no programmer should ever encounter an implementation of printf that pretends to be even somewhat safe, because it might bite him/her elsewhere, in another project based on another C library where printf is just the beartrap it usually is.
IOW, programmers already have assumptions about
*printf(), including how to deal with length limitations and what happens if you don't, and it is best that these assumption remain true whatever project they work with.
Quoted 5 lines
I don't quite understand this. You are saying that we shouldn't modify the existing
printf(),serial_printf()etc. so live within the buffer they use? If I callprintf()and my resulting string is too long for the library then I would much prefer to get truncated output than have to hunt for a wierd crash.
I understand the preference for truncated output, but the output length is primarily in the hands of the caller, through the format stringand possibly also through *nprintf() -- i.e. the caller can only get an output overrun if (s)he does not take the required steps to avoid it.
Quoted 5 lines
It sounds like you are asking for a new
printf(),serial_printf()which provides the facility of limiting the output to n characters, and leave these ones alone. But these functions are not passed a buffer - they use their own and they set the site of it. So I think they should be responsible for enforcing that size.
The existing contract for printf family functions (think wider than U-Boot) does not enforce this responsibility on them.
Quoted 5 lines
If you are asking for a new set of functions -
nprintf(),serial_nprintf(), etc. then I wonder how you can pass the 'n' but not the actual buffer. In my mind you should not do one without the other.So please can you clarify?
I should clarify indeed. My opinion, expressed as a single general rule, is "keep the known semantics of *printf() function family unchanged in U-Boot wrt all other printif implementations around". Thus I think that:
- the printf() function should *not* attempt anything to mitigate length issues beyond what the standard mandates. If a user calls printf(), (s)he is expected to be aware of the risks of overruns, and to take -- if (s)he so decides -- steps to avoid it; besides, the function does not have a way. Conversively, implementers of the printf() function need not consider any specific recovery action with regard to size issues. For instance, why do we have an internal buffer for printf to begin with? The implementation does not need them (and besides, I guess the buffer does not respect the single C99 environmental constraint for printf, that any field should be able to be at least 4095 bytes -- no kidding).
- users who actually wisht to limit outpout ca use either
-- a crafted format string with maximum-sized format specifiers, or
-- a call tp a *nprintf() function into a local buffer of known size followed by a call to fputs().
Quoted 13 lines
Quoted 5 lines
Quoted 4 lines
By the way,
printf()ends up calling the same code, but without limit checking in place. The alternative is to duplicate all the format string processing code (a limit-checking version and an unchecked version) which would be worse.Quoted 7 lines
I don't intend to dictate the way things can be implemented, so the degree of code reuse is an open question as far as I am concerned. I am only voicing my opinion that
*printf()APIs and their contracts should remain identical across all implementations of*printf(), and thus that providing*nprintf()where they don't exist is commandable, but hardeningprintf()is not, since you basically cannot do it without somewhat departing from the de facto standard.
Quoted 4 lines
OK fair enough. People are used to
printf()just working, no matter what the size. I haven't looked at the implementation but I suspect when the buffer fills it outputs it and starts the buffer again .In any case you don't have to worry about it with the GNU C library.
You may also find implementations where the buffer is flushed after each literal part in the format string and after each format specifier output. Or some which emit serial characters as soon as they are produced and use a buffer only for those formats where the ASCII representation cannot be easily constructed left-to-right.
Quoted 3 lines
We probably don't need to go that far in U-Boot, but some simple checking would avoid a nasty surprise for the user. It is obvious from the result that something is truncated, and we can WARN if that helps.
A user who does not expect a nasty surprise from calling printf() with a fair chance of overflowing the output buffer deserves the surprise. :)
Quoted 2 lines
Regards,
Simon
Amicalement,
Signature · 1 line
Albert.
cover Buffer overruns in printf
Hi Albert,
Quoted 26 lines · Albert ARIBAUD
Hi Simon,
Le 25/09/2011 16:50, Simon Glass a ?crit :
Quoted 16 lines
Quoted 10 lines
Basically, printf family functions which do not have the 'n' are *know* by
all -- experienced enough :) -- programmers to be *unsafe* (but to require
less from the caller) and it should remain so: no programmer should ever encounter an implementation of printf that pretends to be even somewhat safe, because it might bite him/her elsewhere, in another project based on
another C library where printf is just the beartrap it usually is.Quoted 5 lines
IOW, programmers already have assumptions about
*printf(), including how to
deal with length limitations and what happens if you don't, and it is best
that these assumption remain true whatever project they work with.Quoted 5 lines
I don't quite understand this. You are saying that we shouldn't modify the existing
printf(),serial_printf()etc. so live within the buffer they use? If I callprintf()and my resulting string is too long for the library then I would much prefer to get truncated output than have to hunt for a wierd crash.
Quoted 4 lines
I understand the preference for truncated output, but the output length is primarily in the hands of the caller, through the format stringand possibly also through
*nprintf()-- i.e. the caller can only get an output overrun if (s)he does not take the required steps to avoid it.
So we are talking about two things here. I am fine with this one - basically people can call sprintf() or snprintf(). If the former then they should be aware of the potential for overflow, if the latter they should prepare for possible truncation.
Quoted 9 lines
Quoted 6 lines
It sounds like you are asking for a new
printf(),serial_printf()which provides the facility of limiting the output to n characters, and leave these ones alone. But these functions are not passed a buffer - they use their own and they set the site of it. So I think they should be responsible for enforcing that size.The existing contract for printf family functions (think wider than U-Boot) does not enforce this responsibility on them.
Let me re-word: printf() and serial_printf() should be responsible for working within the buffer that they use. In the 'existing printf() contract' it is no concern of the user what the size of that buffer may be. In U-Boot we have an implementation that works wholly within that buffer, and that buffer is small, so we are exposing our limitation, either by a buffer overflow crash or truncation. I advocate the latter.
Quoted 22 lines
Quoted 6 lines
If you are asking for a new set of functions -
nprintf(),serial_nprintf(), etc. then I wonder how you can pass the 'n' but not the actual buffer. In my mind you should not do one without the other.So please can you clarify?
I should clarify indeed. My opinion, expressed as a single general rule, is "keep the known semantics of
*printf()function family unchanged in U-Boot wrt all other printif implementations around". Thus I think that:- the
printf()function should *not* attempt anything to mitigate length issues beyond what the standard mandates. If a user callsprintf(), (s)he is expected to be aware of the risks of overruns, ?and to take -- if (s)he so decides -- steps to avoid it; besides, the function does not have a way. Conversively, implementers of theprintf()function need not consider any specific recovery action with regard to size issues. For instance, why do we have an internal buffer for printf to begin with? The implementation does not need them (and besides, I guess the buffer does not respect the single C99 environmental constraint for printf, that any field should be able to be at least 4095 bytes -- no kidding).
Quoted 6 lines
- users who actually wisht to limit outpout ca use either
-- a crafted format string with maximum-sized format specifiers, or
-- a call tp a
*nprintf()function into a local buffer of known size followed by a call tofputs().
I think this last one is clumsy. It could lead to buffers all over U-Boot to work around the printf() limitation. If there is a desire for this (and I'm not saying there is), let's enhance printf() to output bit by bit as it goes (as a separate discussion from this one though). One justification for leaving printf() as it is (but with a size limit instead of a buffer overflow) is that people seldom printf more than a few lines at once.
Quoted 29 lines
Quoted 18 lines
Quoted 6 lines
Quoted 5 lines
By the way,
printf()ends up calling the same code, but without limit checking in place. The alternative is to duplicate all the format string processing code (a limit-checking version and an unchecked version) which would be worse.Quoted 11 lines
I don't intend to dictate the way things can be implemented, so the degree
of code reuse is an open question as far as I am concerned. I am only voicing my opinion that*printf()APIs and their contracts should remain identical across all implementations of*printf(), and thus that providing*nprintf()where they don't exist is commandable, but hardeningprintf()is
not, since you basically cannot do it without somewhat departing from the de
facto standard.Quoted 4 lines
OK fair enough. People are used to
printf()just working, no matter what the size. I haven't looked at the implementation but I suspect when the buffer fills it outputs it and starts the buffer again .In any case you don't have to worry about it with the GNU C library.You may also find implementations where the buffer is flushed after each literal part in the format string and after each format specifier output. Or some which emit serial characters as soon as they are produced and use a buffer only for those formats where the ASCII representation cannot be easily constructed left-to-right.
Quoted 6 lines
Quoted 3 lines
We probably don't need to go that far in U-Boot, but some simple checking would avoid a nasty surprise for the user. It is obvious from the result that something is truncated, and we can WARN if that helps.
A user who does not expect a nasty surprise from calling
printf()with a fair chance of overflowing the output buffer deserves the surprise. :)
For sprintf() I agree - this is well understood and people are aware of it. For printf() I am not so sure.
Regards,
Simon
Quoted 8 lines
Quoted 3 lines
Regards,
SimonAmicalement,
--
Albert.
cover Buffer overruns in printf
Dear Simon Glass,
Quoted 3 lines · In message <CAPnjgZ0y_TWJ4ANEXekGxNpeoJHhkth7hod_3Quu2HVcS=1wHA@mail.gmail.com>…
For
sprintf()I agree - this is well understood and people are aware of it. Forprintf()I am not so sure.
We are a resource limited boot loader. We got for a small footprint, and accept some resulting restrictions, if they are not really severe. THe printf() restriction has not exactly frequently popped up before, so I consider it a non-issue.
Best regards,
Wolfgang Denk
Signature · 7 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Once upon a time, "PC" meant "personal computer". Now it seems to
only mean "Prisoner of Bill". Alas! All my PCs run Unix, and those
include Intel, Sparc, and other processors.
-- Tom "Bring back the non-PC meaning of `PC'" Christiansencover Buffer overruns in printf
In reply to Albert ARIBAUDQuoted 7 lines · Albert ARIBAUD
Hi Simon,
Le 25/09/2011 16:50, Simon Glass a ?crit :
Quoted 3 lines
Quoted 3 lines
Basically, printf family functions which do not have the 'n' are *know* by all -- experienced enough :) -- programmers to be *unsafe* (but to require less from the caller)
printf()/fprintf() are usually safe enough for the things they're used for.
Quoted 4 lines
and it should remain so: no programmer should ever
Quoted 3 lines
Quoted 3 lines
encounter an implementation of printf that pretends to be even somewhat safe, because it might bite him/her elsewhere, in another project based on another C library where printf is just the beartrap it usually is.
And we should mount large spikes on every steering wheel to make people drive more carefully. :-P
Quoted 3 lines
I should clarify indeed. My opinion, expressed as a single general rule, is "keep the known semantics of
*printf()function family unchanged in U-Boot wrt all other printif implementations around". Thus I think that:
FWIW, Linux's printk() truncates output if it exceeds the internal buffer. glibc's is an ugly mess, but appears to not need a fixed printf buffer -- it streams output into its file buffering mechanism. That there may be some crappy implementations out there is no excuse for making these functions difficult to use everywhere.
Quoted 4 lines
Conversively, implementers of the
printf()function need not consider any specific recovery action with regard to size issues. For instance, why do we have an internal buffer for printf to begin with? The implementation does not need them
Apparently this implementation does. I suppose you could rewrite the code to not need one, but is that really worthwhile here, compared to this easy and virtually cost-free (once you have snprintf) form of damage control? It's just passing in a meaningful number to vsnprintf instead of INT_MAX. You could save some bytes by removing vsprintf(), as well.
Quoted 3 lines
(and besides, I guess the buffer
does not respect the single C99 environmental constraint for printf, that any field should be able to be at least 4095 bytes -- no kidding).
That this minimum is more than most boards allow for the entire output, and that it is board-specific (so it could work for one board but fail for another), are all the more reason to want some safety here. I'd much rather see a truncated message (and proceed to fix the obvious bug) than have to debug corruption and possibly recover a bricked board.
Quoted 1 line
- users who actually wisht to limit outpout ca use either
You say "actually wish to limit output" as if "let it corrupt memory if it's too large" is the normal thing to want.
-scott
cover Buffer overruns in printf
Quoted 4 lines · Scott Wood
Quoted 1 line
- users who actually wisht to limit outpout ca use either
You say "actually wish to limit output" as if "let it corrupt memory if it's too large" is the normal thing to want.
What I meant was "users who actually want to limit output explicitly by truncating it rather than implicitly by always outputting small enough text or crafting limitations in the format string specifiers, ..."
Quoted 1 line
-scott
Amicalement,
Signature · 1 line
Albert.
cover Buffer overruns in printf
Hi,
Quoted 11 lines · Albert ARIBAUD
Quoted 4 lines · Scott Wood
Quoted 1 line
- users who actually wisht to limit outpout ca use either
You say "actually wish to limit output" as if "let it corrupt memory if it's too large" is the normal thing to want.
What I meant was "users who actually want to limit output explicitly by truncating it rather than implicitly by always outputting small enough text or crafting limitations in the format string specifiers, ..."
Quoted 6 lines
Quoted 1 line
-scott
Amicalement,
--
Albert.
Just to follow up this thread, I am going to drop the network patch and resubmit the rest of it. This will make snprintf() available in U-Boot.
Regards,
Simon
cover Buffer overruns in printf
Dear Simon Glass,
Quoted 4 lines · In message <CAPnjgZ3hYmXEHr8MT0deZ054kuOxkNDt4Sa+nVPSzPAdAQFf0w@mail.gmail.com>…
Just to follow up this thread, I am going to drop the network patch and resubmit the rest of it. This will make
snprintf()available in U-Boot.
Without code that uses it? We don't accept dead code...
Best regards,
Wolfgang Denk
Signature · 4 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de Due to lack of disk space, this fortune database has been discontinued.
cover Buffer overruns in printf
Hi Wolfgang,
Quoted 9 lines · Wolfgang Denk
Dear Simon Glass,
Quoted 4 lines · In message <CAPnjgZ3hYmXEHr8MT0deZ054kuOxkNDt4Sa+nVPSzPAdAQFf0w@mail.gmail.com>…
Just to follow up this thread, I am going to drop the network patch and resubmit the rest of it. This will make
snprintf()available in U-Boot.Without code that uses it? ?We don't accept dead code...
It is used by printf() and the like - please see console.c.
Regards,
Simon
Quoted 11 lines
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, ? ? MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de Due to lack of disk space, this fortune database has been discontinued.
cover Buffer overruns in printf
In reply to Simon GlassDear Simon Glass,
Quoted 7 lines · In message <[email protected]> you wrote:
The printf family of functions in U-Boot cannot deal with a situation where the caller provides a buffer which turns out to be too small for the format string. This can result in buffer overflows, stack overflows and other bad behavior.
This patch series tidies this up in the common
vsprintf.ccode, and also some network code (as an example of where this might lead).
What's the impact of this patch set on the memory footprint of typical configurations?
Best regards,
Wolfgang Denk
Signature · 4 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Nail here --X-- for new monitor.cover Buffer overruns in printf
Hi Wolfgang,
Quoted 8 lines · Wolfgang Denk
Dear Simon Glass,
Quoted 5 lines · In message <[email protected]> you wrote:
The printf family of functions in U-Boot cannot deal with a situation where the caller provides a buffer which turns out to be too small for the format string. This can result in buffer overflows, stack overflows and other bad behavior.
Quoted 5 lines
Quoted 2 lines
This patch series tidies this up in the common
vsprintf.ccode, and also some network code (as an example of where this might lead).What's the impact of this patch set on the memory footprint of typical configurations?
Good question. The short answer with my ARMv7 compiler (gcc-4.4.3_cos_gg_53174) is 328 bytes, about 10% increase to code size vsprintf.o.
The newly added functions (snprintf, vscnprintf, scnprintf) are a total of 116 bytes.
The changes to number(), string() and vsprintf() to make them respect an end pointer increase size by 80, 20 and 80 bytes respectively.
Total text size for existing vsprintf.o functions goes from 0xc10 (3088) to 0xd58 (3416), or 328 bytes. Of this 116 bytes is the new functions and the rest is dealing with the end pointer. There is no data.
Regards,
Simon
Quoted 11 lines
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, ? ? MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de ? ? ? ? ? ? ? ? ?Nail here --X-- for new monitor.