Skip to contentSkip to conversation

Buffer overruns in printf

PATCH New Simon Glass 8 participants 41 messages Sep 23, 2011 – Oct 10, 2011

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 0af471a..e7b6e43 100644
@@ -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
new file mode 100644
index 0000000..1021291
@@ -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
#2 lore raw

PATCH 2/4 Add safe vsnprintf and snprintf library functions

In reply to 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.

---
 include/common.h |    8 ++-
 lib/vsprintf.c   |  316 ++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 256 insertions(+), 68 deletions(-)
include/common.h +7 -1
index d244bd4..fbcc55f 100644
@@ -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
#3 lore raw

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

#4 lore raw

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

#5 lore raw

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.html

So 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

#6 lore raw

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.html

So 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

#7 lore raw

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

#8 lore raw

PATCH 3/4 Make printf and vprintf safe from buffer overruns

In reply to 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.

---
 common/console.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)
common/console.c +5 -5
index 8c650e0..6057e9a 100644
@@ -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
#9 lore raw

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.

---
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

#10 lore raw

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

---
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

#11 lore raw

PATCH 3/4 Make printf and vprintf safe from buffer overruns

In reply to Simon Glass

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
-------------- 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

#12 lore raw

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

#13 lore raw

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

#14 lore raw

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_PBSIZE is 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

#15 lore raw

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_PBSIZE is the current standard

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.

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>
#16 lore raw

PATCH 3/4 Make printf and vprintf safe from buffer overruns

In reply to Simon Glass

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.

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
#17 lore raw

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

#18 lore raw

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
#19 lore raw

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

#20 lore raw

PATCH 4/4 Use snprintf() in network code

In reply to Simon Glass

This 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
index 5911b1c..30711d4 100644
@@ -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
index 7a60583..28e45c0 100644
@@ -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
index f76f60d..d1e894e 100644
@@ -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
index a893e02..c4f6a59 100644
@@ -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
#21 lore raw

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 of sprintf(). 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 -1
 
 	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.

net/eth.c int eth_getenv_enetaddr_by_index(const char *base_name, int index, · line 63

Quoted 4 lines
net/eth.c +2 -1
 	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)

net/eth.c static int eth_mac_skip(int index) · line 75

Quoted 4 lines
net/eth.c +2 -1
 	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 -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

#22 lore raw

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 of sprintf(). 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

#23 lore raw

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 -1
 
      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 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_name could 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 use snprintf() or assert() 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

#24 lore raw

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_name could 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 ;]).

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 use snprintf() or assert() 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

#25 lore raw

cover Buffer overruns in printf

In reply to Simon Glass

Hi 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.
#26 lore raw

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.

#27 lore raw

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.
#28 lore raw

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 of printf(), 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

#29 lore raw

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 of printf(), 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.
#30 lore raw

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 of printf(), 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 hardening printf() 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,
Simon

Amicalement,
--
Albert.

#31 lore raw

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 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.

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 hardening printf() 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.
#32 lore raw

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 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.

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 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).

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 to fputs().

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 hardening printf() 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,
Simon

Amicalement,
--
Albert.

#33 lore raw

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. For printf() 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'" Christiansen
#34 lore raw

cover Buffer overruns in printf

In reply to Albert ARIBAUD
Quoted 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

#35 lore raw

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.
#36 lore raw

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

#37 lore raw

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.
#38 lore raw

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.

#39 lore raw

cover Buffer overruns in printf

In reply to Simon Glass

Dear 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.c code, 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.
#40 lore raw

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.c code, 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.