Skip to content

Commit ac8d679

Browse files
committed
logsrvd_conv_syslog: fix buffer overflow on large messages
The code tried to reallocate a dynamic buffer in 1KiB increments but did not correctly handle a message larger than 1KiB. We now use a static 4KiB buffer and truncate log message larger than that.
1 parent 54bc3e7 commit ac8d679

File tree

1 file changed

+9
-16
lines changed

1 file changed

+9
-16
lines changed

logsrvd/logsrvd_conf.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,9 +1422,9 @@ static int
14221422
logsrvd_conv_syslog(int num_msgs, const struct sudo_conv_message msgs[],
14231423
struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
14241424
{
1425-
char *buf = NULL, *cp = NULL;
14261425
const char *progname;
1427-
size_t proglen, bufsize = 0;
1426+
char buf[4096], *cp, *ep;
1427+
size_t proglen;
14281428
int i;
14291429
debug_decl(logsrvd_conv_syslog, SUDO_DEBUG_UTIL);
14301430

@@ -1442,10 +1442,11 @@ logsrvd_conv_syslog(int num_msgs, const struct sudo_conv_message msgs[],
14421442
*/
14431443
progname = getprogname();
14441444
proglen = strlen(progname);
1445-
for (i = 0; i < num_msgs; i++) {
1445+
cp = buf;
1446+
ep = buf + sizeof(buf);
1447+
for (i = 0; i < num_msgs && ep - cp > 1; i++) {
14461448
const char *msg = msgs[i].msg;
14471449
size_t len = strlen(msg);
1448-
size_t used = (size_t)(cp - buf);
14491450

14501451
/* Strip leading "sudo_logsrvd: " prefix. */
14511452
if (strncmp(msg, progname, proglen) == 0) {
@@ -1470,25 +1471,17 @@ logsrvd_conv_syslog(int num_msgs, const struct sudo_conv_message msgs[],
14701471
if (len == 0)
14711472
continue;
14721473

1473-
if (len >= bufsize - used) {
1474-
bufsize += 1024;
1475-
char *tmp = realloc(buf, bufsize);
1476-
if (tmp == NULL) {
1477-
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1478-
free(buf);
1479-
debug_return_int(-1);
1480-
}
1481-
buf = tmp;
1482-
cp = tmp + used;
1474+
if (len >= (size_t)(ep - cp)) {
1475+
/* Message too long, truncate. */
1476+
len = (size_t)(ep - cp) - 1;
14831477
}
14841478
memcpy(cp, msg, len);
14851479
cp[len] = '\0';
14861480
cp += len;
14871481
}
1488-
if (buf != NULL) {
1482+
if (cp != buf) {
14891483
openlog(progname, 0, logsrvd_config->syslog.server_facility);
14901484
syslog(LOG_ERR, "%s", buf);
1491-
free(buf);
14921485

14931486
/* Restore old syslog settings. */
14941487
if (logsrvd_config->eventlog.log_type == EVLOG_SYSLOG)

0 commit comments

Comments
 (0)