aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-08-01 06:53:03 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-08-01 06:53:03 +0200
commite2944af43eeb95ec612a48cc930a71f9e6a2f219 (patch)
treeef69ffd442ca5a4fdc0a00f0d6e625f0619df85d
parent6d48d3ee2a5a6b5bded1591952d8105fafdf783a (diff)
downloadbusybox-w32-e2944af43eeb95ec612a48cc930a71f9e6a2f219.tar.gz
busybox-w32-e2944af43eeb95ec612a48cc930a71f9e6a2f219.tar.bz2
busybox-w32-e2944af43eeb95ec612a48cc930a71f9e6a2f219.zip
libbb: prevent resursion on malloc failure
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--libbb/verror_msg.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/libbb/verror_msg.c b/libbb/verror_msg.c
index 58846d56e..506b9066a 100644
--- a/libbb/verror_msg.c
+++ b/libbb/verror_msg.c
@@ -15,7 +15,7 @@ const char *msg_eol = "\n";
15 15
16void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) 16void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr)
17{ 17{
18 char *msg; 18 char *msg, *msg1;
19 int applet_len, strerr_len, msgeol_len, used; 19 int applet_len, strerr_len, msgeol_len, used;
20 20
21 if (!logmode) 21 if (!logmode)
@@ -36,27 +36,36 @@ void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr)
36 applet_len = strlen(applet_name) + 2; /* "applet: " */ 36 applet_len = strlen(applet_name) + 2; /* "applet: " */
37 strerr_len = strerr ? strlen(strerr) : 0; 37 strerr_len = strerr ? strlen(strerr) : 0;
38 msgeol_len = strlen(msg_eol); 38 msgeol_len = strlen(msg_eol);
39 /* can't use xrealloc: it calls error_msg on failure,
40 * that may result in a recursion */
39 /* +3 is for ": " before strerr and for terminating NUL */ 41 /* +3 is for ": " before strerr and for terminating NUL */
40 msg = xrealloc(msg, applet_len + used + strerr_len + msgeol_len + 3); 42 msg1 = realloc(msg, applet_len + used + strerr_len + msgeol_len + 3);
41 /* TODO: maybe use writev instead of memmoving? Need full_writev? */ 43 if (!msg1) {
42 memmove(msg + applet_len, msg, used); 44 msg[used++] = '\n'; /* overwrites NUL */
43 used += applet_len; 45 applet_len = 0;
44 strcpy(msg, applet_name); 46 } else {
45 msg[applet_len - 2] = ':'; 47 msg = msg1;
46 msg[applet_len - 1] = ' '; 48 /* TODO: maybe use writev instead of memmoving? Need full_writev? */
47 if (strerr) { 49 memmove(msg + applet_len, msg, used);
48 if (s[0]) { /* not perror_nomsg? */ 50 used += applet_len;
49 msg[used++] = ':'; 51 strcpy(msg, applet_name);
50 msg[used++] = ' '; 52 msg[applet_len - 2] = ':';
53 msg[applet_len - 1] = ' ';
54 if (strerr) {
55 if (s[0]) { /* not perror_nomsg? */
56 msg[used++] = ':';
57 msg[used++] = ' ';
58 }
59 strcpy(&msg[used], strerr);
60 used += strerr_len;
51 } 61 }
52 strcpy(&msg[used], strerr); 62 strcpy(&msg[used], msg_eol);
53 used += strerr_len; 63 used += msgeol_len;
54 } 64 }
55 strcpy(&msg[used], msg_eol);
56 65
57 if (logmode & LOGMODE_STDIO) { 66 if (logmode & LOGMODE_STDIO) {
58 fflush(stdout); 67 fflush(stdout);
59 full_write(STDERR_FILENO, msg, used + msgeol_len); 68 full_write(STDERR_FILENO, msg, used);
60 } 69 }
61 if (logmode & LOGMODE_SYSLOG) { 70 if (logmode & LOGMODE_SYSLOG) {
62 syslog(LOG_ERR, "%s", msg + applet_len); 71 syslog(LOG_ERR, "%s", msg + applet_len);