@@ -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