summaryrefslogtreecommitdiffstats
path: root/src/core/xfer.c
diff options
context:
space:
mode:
authorMichael Brown2012-04-23 21:17:24 +0200
committerMichael Brown2012-04-23 21:30:48 +0200
commitde2616165be6d57143981265669fd730669fb13f (patch)
treec0b43d9daa31da029f4ccbfdcb12f2796eeb5a45 /src/core/xfer.c
parent[realtek] Update link state when device is opened (diff)
downloadipxe-de2616165be6d57143981265669fd730669fb13f.tar.gz
ipxe-de2616165be6d57143981265669fd730669fb13f.tar.xz
ipxe-de2616165be6d57143981265669fd730669fb13f.zip
[xfer] Avoid using stack-allocated memory in xfer_printf()
xfer_printf() occasionally has to deal with strings that are potentially long, such as HTTP URIs with multiple query parameters. Allocating these on the stack can lead to stack overruns and memory corruption. Fix by using vasprintf() instead of a stack allocation. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core/xfer.c')
-rw-r--r--src/core/xfer.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/core/xfer.c b/src/core/xfer.c
index 4d7d6b43..037c089a 100644
--- a/src/core/xfer.c
+++ b/src/core/xfer.c
@@ -19,6 +19,7 @@
FILE_LICENCE ( GPL2_OR_LATER );
#include <string.h>
+#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ipxe/iobuf.h>
@@ -297,17 +298,28 @@ int xfer_deliver_raw ( struct interface *intf, const void *data, size_t len ) {
*/
int xfer_vprintf ( struct interface *intf, const char *format,
va_list args ) {
- size_t len;
va_list args_tmp;
+ char *buf;
+ int len;
+ int rc;
+ /* Create temporary string */
va_copy ( args_tmp, args );
- len = vsnprintf ( NULL, 0, format, args );
- {
- char buf[len + 1];
- vsnprintf ( buf, sizeof ( buf ), format, args_tmp );
- va_end ( args_tmp );
- return xfer_deliver_raw ( intf, buf, len );
+ len = vasprintf ( &buf, format, args );
+ if ( len < 0 ) {
+ rc = len;
+ goto err_asprintf;
}
+ va_end ( args_tmp );
+
+ /* Transmit string */
+ if ( ( rc = xfer_deliver_raw ( intf, buf, len ) ) != 0 )
+ goto err_deliver;
+
+ err_deliver:
+ free ( buf );
+ err_asprintf:
+ return rc;
}
/**