Skip to content

Commit aaabb6e

Browse files
committed
auditd: bound formatted message length
1 parent 2562eb7 commit aaabb6e

1 file changed

Lines changed: 36 additions & 11 deletions

File tree

src/auditd-event.c

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,21 @@ static void replace_event_msg(struct auditd_event *e, const char *buf)
299299
}
300300
}
301301

302+
/*
303+
* Cap snprintf's return value to the bytes actually stored in format_buf.
304+
* nlen is the number of bytes that would have been written, limit is the
305+
* destination buffer size passed to snprintf, and the return value is the
306+
* number of bytes available in format_buf excluding the trailing NUL.
307+
*/
308+
static int clamp_format_len(int nlen, size_t limit)
309+
{
310+
if (nlen < 1)
311+
return 0;
312+
if ((size_t)nlen >= limit)
313+
return limit - 1;
314+
return nlen;
315+
}
316+
302317
/*
303318
* This function will take an audit structure and return a
304319
* text buffer that's formatted for writing to disk. If there is
@@ -309,19 +324,24 @@ static int format_raw(const struct audit_reply *rep)
309324
{
310325
char *ptr;
311326
int nlen;
327+
size_t limit;
312328

313329
format_buf[0] = 0;
314330

315331
if (rep == NULL) {
316-
if (config->node_name_format != N_NONE)
317-
nlen = snprintf(format_buf, FORMAT_BUF_LEN - 32,
332+
if (config->node_name_format != N_NONE) {
333+
limit = FORMAT_BUF_LEN - 32;
334+
nlen = snprintf(format_buf, limit,
318335
"node=%s type=DAEMON_ERR op=format-raw msg=NULL res=failed",
319336
config->node_name);
320-
else
321-
nlen = snprintf(format_buf, MAX_AUDIT_MESSAGE_LENGTH,
337+
} else {
338+
limit = MAX_AUDIT_MESSAGE_LENGTH;
339+
nlen = snprintf(format_buf, limit,
322340
"type=DAEMON_ERR op=format-raw msg=NULL res=failed");
341+
}
323342

324-
if (nlen < 1)
343+
nlen = clamp_format_len(nlen, limit);
344+
if (nlen == 0)
325345
return 0;
326346
} else {
327347
int len;
@@ -343,16 +363,19 @@ static int format_raw(const struct audit_reply *rep)
343363

344364
// Note: This can truncate messages if
345365
// MAX_AUDIT_MESSAGE_LENGTH is too small
346-
if (config->node_name_format != N_NONE)
347-
nlen = snprintf(format_buf, FORMAT_BUF_LEN - 32,
366+
if (config->node_name_format != N_NONE) {
367+
limit = FORMAT_BUF_LEN - 32;
368+
nlen = snprintf(format_buf, limit,
348369
"node=%s type=%s msg=%.*s",
349370
config->node_name, type, len, message);
350-
else
351-
nlen = snprintf(format_buf,
352-
MAX_AUDIT_MESSAGE_LENGTH - 32,
371+
} else {
372+
limit = MAX_AUDIT_MESSAGE_LENGTH - 32;
373+
nlen = snprintf(format_buf, limit,
353374
"type=%s msg=%.*s", type, len, message);
375+
}
354376

355-
if (nlen < 1)
377+
nlen = clamp_format_len(nlen, limit);
378+
if (nlen == 0)
356379
return 0;
357380

358381
/* Replace \n with space so it looks nicer. */
@@ -479,6 +502,8 @@ static const char *format_enrich(const struct audit_reply *rep)
479502
mlen = format_raw(rep);
480503

481504
// How much room is left?
505+
if (mlen >= FORMAT_BUF_LEN)
506+
return format_buf;
482507
len = FORMAT_BUF_LEN - mlen;
483508
if (len <= MIN_SPACE_LEFT)
484509
return format_buf;

0 commit comments

Comments
 (0)