From 32e9dccc33056547a471cc8bde211feb6f2861eb Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Mon, 3 Nov 2014 16:08:43 -0600 Subject: [PATCH] Fix the implementation of vasprintf to work with ORCA/C's varargs implementation. Also, shrink the stack-allocated buffer in it. This code could theoretically break if the ORCA/C varargs implementation changed, but it should be OK in practice. Also removed some unused code in libbb/xfuncs.printf.c that includes potentially problematic varargs use (defining varargs functions but not necessarily calling va_start/va_end in them). --- libbb/platform.c | 23 ++++++++++++--- libbb/xfuncs.printf.c | 69 ------------------------------------------- 2 files changed, 19 insertions(+), 73 deletions(-) diff --git a/libbb/platform.c b/libbb/platform.c index 8d90ca4e9..e3f91f7bf 100644 --- a/libbb/platform.c +++ b/libbb/platform.c @@ -36,27 +36,42 @@ int FAST_FUNC usleep(unsigned usec) #endif #ifndef HAVE_VASPRINTF +#ifndef __ORCAC__ +# define VASPRINTF_BUF_SIZE 128 +#else +# define VASPRINTF_BUF_SIZE 8 +#endif + int FAST_FUNC vasprintf(char **string_ptr, const char *format, va_list p) { int r; va_list p2; - char buf[128]; + char buf[VASPRINTF_BUF_SIZE]; +#ifndef __ORCAC__ va_copy(p2, p); - r = vsnprintf(buf, 128, format, p); - va_end(p); +#else + // ORCA/C doesn't have va_copy, so copy it manually instead. + // Don't call va_end on the copy, because that would mess up the stack. + memcpy(p2, p, sizeof(va_list)); +#endif + r = vsnprintf(buf, VASPRINTF_BUF_SIZE, format, p); /* Note: can't use xstrdup/xmalloc, they call vasprintf (us) on failure! */ - if (r < 128) { + if (r < VASPRINTF_BUF_SIZE) { +#ifndef __ORCAC__ va_end(p2); +#endif *string_ptr = strdup(buf); return (*string_ptr ? r : -1); } *string_ptr = malloc(r+1); r = (*string_ptr ? vsnprintf(*string_ptr, r+1, format, p2) : -1); +#ifndef __ORCAC__ va_end(p2); +#endif return r; } diff --git a/libbb/xfuncs.printf.c b/libbb/xfuncs.printf.c index d62a6bc29..8af207e8c 100644 --- a/libbb/xfuncs.printf.c +++ b/libbb/xfuncs.printf.c @@ -477,75 +477,6 @@ void FAST_FUNC selinux_or_die(void) #endif } -int FAST_FUNC ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) -{ - int ret; - va_list p; - - ret = ioctl(fd, request, argp); - if (ret < 0) { - va_start(p, fmt); - bb_verror_msg(fmt, p, strerror(errno)); - /* xfunc_die can actually longjmp, so be nice */ - va_end(p); - xfunc_die(); - } - return ret; -} - -int FAST_FUNC ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) -{ - va_list p; - int ret = ioctl(fd, request, argp); - - if (ret < 0) { - va_start(p, fmt); - bb_verror_msg(fmt, p, strerror(errno)); - va_end(p); - } - return ret; -} - -#if ENABLE_IOCTL_HEX2STR_ERROR -int FAST_FUNC bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) -{ - int ret; - - ret = ioctl(fd, request, argp); - if (ret < 0) - bb_simple_perror_msg(ioctl_name); - return ret; -} -int FAST_FUNC bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) -{ - int ret; - - ret = ioctl(fd, request, argp); - if (ret < 0) - bb_simple_perror_msg_and_die(ioctl_name); - return ret; -} -#else -int FAST_FUNC bb_ioctl_or_warn(int fd, unsigned request, void *argp) -{ - int ret; - - ret = ioctl(fd, request, argp); - if (ret < 0) - bb_perror_msg("ioctl %#x failed", request); - return ret; -} -int FAST_FUNC bb_xioctl(int fd, unsigned request, void *argp) -{ - int ret; - - ret = ioctl(fd, request, argp); - if (ret < 0) - bb_perror_msg_and_die("ioctl %#x failed", request); - return ret; -} -#endif - #if BB_MMU pid_t FAST_FUNC xfork(void) {