Skip to content

Commit f40d81a

Browse files
committed
Make kvlog more safe if buffer is too small
1 parent 5580f12 commit f40d81a

File tree

1 file changed

+40
-6
lines changed

1 file changed

+40
-6
lines changed

libc/src/stdio/kvlog.c

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,45 @@
2727
/**
2828
*
2929
*/
30-
void kvlog(const char* message, va_list l) {
31-
uint32_t msglen = strlen(message);
32-
uint32_t buflen = msglen * 4;
33-
char* buf = (char*) malloc(buflen);
34-
vsnprintf(buf, buflen, message, l);
35-
g_log(buf);
30+
void kvlog(const char* message, va_list l)
31+
{
32+
va_list lc;
33+
va_copy(lc, l);
34+
35+
// First try
36+
uint32_t messageLen = strlen(message);
37+
uint32_t bufLen = messageLen * 4;
38+
39+
char* buf = malloc(bufLen);
40+
if(!buf)
41+
{
42+
g_log("failed to allocate buffer for kernel logging");
43+
return;
44+
}
45+
46+
int printed = vsnprintf(buf, bufLen, message, l);
47+
int success = printed == messageLen - 1;
48+
if(success)
49+
g_log(buf);
50+
3651
free(buf);
52+
53+
// Buffer too small? Second try
54+
if(!success)
55+
{
56+
bufLen = messageLen * 8;
57+
buf = (char*) malloc(bufLen);
58+
if(!buf)
59+
{
60+
g_log("failed to allocate buffer for kernel logging on retry");
61+
return;
62+
}
63+
64+
vsnprintf(buf, bufLen, message, lc);
65+
g_log(buf);
66+
67+
free(buf);
68+
}
69+
70+
va_end(lc);
3771
}

0 commit comments

Comments
 (0)