4141#include <stdlib.h>
4242#include <limits.h>
4343#include <string.h>
44+ #include <sys/types.h>
4445
4546#include "common/debug_priv.h"
4647
4748#define SYSCTL_CMD "/sbin/sysctl -ae"
49+ #define SYSCTL_VALUE_MAX (64 * 1024)
4850#elif defined(OS_APPLE )
4951#include <ctype.h>
5052#include <stdio.h>
5153#include <stdlib.h>
5254#include <limits.h>
5355#include <string.h>
56+ #include <sys/types.h>
5457
5558#include "common/debug_priv.h"
5659
5760/* On macOS sysctl(8) lives under /usr/sbin */
5861#define SYSCTL_CMD "/usr/sbin/sysctl -ae"
62+ #define SYSCTL_VALUE_MAX (64 * 1024)
5963#endif
6064
6165#if defined(OS_LINUX )
@@ -349,13 +353,25 @@ static int sysctl_parse_line(char *line, char **mib, char **sysval)
349353 return 1 ;
350354}
351355
352- static int sysctl_append_value (char * * value , size_t * value_len , const char * line )
356+ static int sysctl_append_value (char * * value , size_t * value_len , const char * line , int * truncated )
353357{
354- size_t line_len , new_len ;
358+ size_t line_len , append_len , new_len ;
355359 char * new_value ;
356360
361+ if (* truncated )
362+ return 0 ;
363+
357364 line_len = strlen (line );
358- new_len = * value_len + line_len + (* value_len > 0 ? 1 : 0 ) + 1 ;
365+ if (* value_len >= SYSCTL_VALUE_MAX ) {
366+ * truncated = 1 ;
367+ return 0 ;
368+ }
369+
370+ append_len = line_len ;
371+ if (* value_len + append_len > SYSCTL_VALUE_MAX )
372+ append_len = SYSCTL_VALUE_MAX - * value_len ;
373+
374+ new_len = * value_len + append_len + (* value_len > 0 ? 1 : 0 ) + 1 ;
359375 new_value = realloc (* value , new_len );
360376 if (new_value == NULL )
361377 return -1 ;
@@ -364,8 +380,13 @@ static int sysctl_append_value(char **value, size_t *value_len, const char *line
364380 if (* value_len > 0 )
365381 new_value [(* value_len )++ ] = '\n' ;
366382
367- memcpy (new_value + * value_len , line , line_len + 1 );
368- * value_len += line_len ;
383+ memcpy (new_value + * value_len , line , append_len );
384+ * value_len += append_len ;
385+ new_value [* value_len ] = '\0' ;
386+
387+ if (append_len < line_len )
388+ * truncated = 1 ;
389+
369390 return 0 ;
370391}
371392
@@ -526,14 +547,17 @@ int sysctl_probe_offline_mode_supported(void)
526547int sysctl_probe_main (probe_ctx * ctx , void * probe_arg )
527548{
528549 FILE * fp ;
529- char output [LINE_MAX ];
550+ char * output = NULL ;
551+ size_t output_cap = 0 ;
552+ ssize_t output_len ;
530553 SEXP_t * name_entity , * probe_in ;
531554 oval_schema_version_t over ;
532555 int over_cmp ;
533556 int ret = 0 ;
534557 char * current_mib = NULL ;
535558 char * current_value = NULL ;
536559 size_t current_value_len = 0 ;
560+ int current_value_truncated = 0 ;
537561
538562 probe_in = probe_ctx_getobject (ctx );
539563 name_entity = probe_obj_getent (probe_in , "name" , 1 );
@@ -558,7 +582,7 @@ int sysctl_probe_main(probe_ctx *ctx, void *probe_arg)
558582 return (PROBE_EFATAL );
559583 }
560584
561- while (fgets ( output , sizeof ( output ), fp )) {
585+ while (( output_len = getline ( & output , & output_cap , fp )) != -1 ) {
562586 char * mib , * sysval , * newline ;
563587
564588 newline = strchr (output , '\n' );
@@ -579,37 +603,47 @@ int sysctl_probe_main(probe_ctx *ctx, void *probe_arg)
579603 current_mib = strdup (mib );
580604 current_value = NULL ;
581605 current_value_len = 0 ;
606+ current_value_truncated = 0 ;
582607 if (current_mib == NULL ) {
583608 dE ("Failed to allocate new sysctl name buffer" );
584609 ret = PROBE_ENOENT ;
585610 goto cleanup ;
586611 }
587612
588- if (sysctl_append_value (& current_value , & current_value_len , sysval ) != 0 ) {
613+ if (sysctl_append_value (& current_value , & current_value_len , sysval ,
614+ & current_value_truncated ) != 0 ) {
589615 dE ("Failed to append sysctl value" );
590616 ret = PROBE_ENOENT ;
591617 goto cleanup ;
592618 }
593619
620+ if (current_value_truncated )
621+ dD ("Truncated sysctl value for %s to %d bytes" , current_mib , SYSCTL_VALUE_MAX );
622+
594623 continue ;
595624 }
596625
597626 if (current_mib == NULL )
598627 continue ;
599628
600- if (sysctl_append_value (& current_value , & current_value_len , output ) != 0 ) {
629+ if (sysctl_append_value (& current_value , & current_value_len , output ,
630+ & current_value_truncated ) != 0 ) {
601631 dE ("Failed to append sysctl continuation value" );
602632 ret = PROBE_ENOENT ;
603633 goto cleanup ;
604634 }
605- }
635+
636+ if (current_value_truncated )
637+ dD ("Truncated sysctl value for %s to %d bytes" , current_mib , SYSCTL_VALUE_MAX );
638+ }
606639
607640 if (current_mib != NULL )
608641 ret = sysctl_collect_item (ctx , name_entity , current_mib ,
609642 current_value != NULL ? current_value : "" ,
610643 over_cmp );
611644
612645cleanup :
646+ free (output );
613647 free (current_mib );
614648 free (current_value );
615649 pclose (fp );
0 commit comments