@@ -369,10 +369,105 @@ static int sysctl_append_value(char **value, size_t *value_len, const char *line
369369 return 0 ;
370370}
371371
372+ static char * sysctl_sanitize_single_value (const char * value )
373+ {
374+ size_t i , in_len , out_len = 0 ;
375+ char * sanitized ;
376+
377+ in_len = strlen (value );
378+ sanitized = malloc (in_len + 1 );
379+ if (sanitized == NULL )
380+ return NULL ;
381+
382+ for (i = 0 ; i < in_len ; ++ i ) {
383+ unsigned char ch = (unsigned char ) value [i ];
384+
385+ if (!isprint (ch ) && !isspace (ch ))
386+ continue ;
387+
388+ sanitized [out_len ++ ] = value [i ];
389+ }
390+
391+ while (out_len > 0 && sanitized [out_len - 1 ] == '\n' )
392+ -- out_len ;
393+
394+ sanitized [out_len ] = '\0' ;
395+ return sanitized ;
396+ }
397+
398+ static int sysctl_sanitize_multi_value (const char * value , char * * buffer_out , char * * * values_out )
399+ {
400+ size_t i , in_len , value_count = 0 , value_index = 0 ;
401+ int in_value = 0 ;
402+ char * buffer ;
403+ char * * values ;
404+
405+ in_len = strlen (value );
406+ buffer = malloc (in_len + 1 );
407+ if (buffer == NULL )
408+ return -1 ;
409+
410+ memcpy (buffer , value , in_len + 1 );
411+
412+ for (i = 0 ; i < in_len ; ++ i ) {
413+ unsigned char ch = (unsigned char ) buffer [i ];
414+
415+ if ((!isprint (ch ) && !isspace (ch )) || buffer [i ] == '\n' )
416+ buffer [i ] = '\0' ;
417+
418+ if (buffer [i ] == '\0' ) {
419+ in_value = 0 ;
420+ continue ;
421+ }
422+
423+ if (!in_value ) {
424+ ++ value_count ;
425+ in_value = 1 ;
426+ }
427+ }
428+
429+ if (value_count == 0 )
430+ value_count = 1 ;
431+
432+ values = calloc (value_count + 1 , sizeof (char * ));
433+ if (values == NULL ) {
434+ free (buffer );
435+ return -1 ;
436+ }
437+
438+ if (buffer [0 ] == '\0' && value_count == 1 ) {
439+ values [0 ] = buffer ;
440+ * buffer_out = buffer ;
441+ * values_out = values ;
442+ return 0 ;
443+ }
444+
445+ in_value = 0 ;
446+ for (i = 0 ; i < in_len ; ++ i ) {
447+ if (buffer [i ] == '\0' ) {
448+ in_value = 0 ;
449+ continue ;
450+ }
451+
452+ if (!in_value ) {
453+ values [value_index ++ ] = buffer + i ;
454+ in_value = 1 ;
455+ }
456+ }
457+
458+ * buffer_out = buffer ;
459+ * values_out = values ;
460+ return 0 ;
461+ }
462+
372463static int sysctl_collect_item (probe_ctx * ctx , SEXP_t * name_entity ,
373- const char * mib , const char * sysval )
464+ const char * mib , const char * sysval , int over_cmp )
374465{
375466 SEXP_t * item , * se_mib ;
467+ char * sanitized_value = NULL ;
468+ char * sanitized_buffer = NULL ;
469+ char * * sanitized_values = NULL ;
470+ int ret = 0 ;
376471
377472 se_mib = SEXP_string_new (mib , strlen (mib ));
378473 if (!se_mib ) {
@@ -381,21 +476,46 @@ static int sysctl_collect_item(probe_ctx *ctx, SEXP_t *name_entity,
381476 }
382477
383478 if (probe_entobj_cmp (name_entity , se_mib ) == OVAL_RESULT_TRUE ) {
384- item = probe_item_create (OVAL_UNIX_SYSCTL , NULL ,
385- "name" , OVAL_DATATYPE_SEXP , se_mib ,
386- "value" , OVAL_DATATYPE_STRING , sysval ,
387- NULL );
479+ if (over_cmp >= 0 ) {
480+ if (sysctl_sanitize_multi_value (sysval , & sanitized_buffer , & sanitized_values ) != 0 ) {
481+ dE ("Failed to sanitize sysctl value list" );
482+ ret = PROBE_ENOENT ;
483+ goto cleanup ;
484+ }
485+
486+ item = probe_item_create (OVAL_UNIX_SYSCTL , NULL ,
487+ "name" , OVAL_DATATYPE_SEXP , se_mib ,
488+ "value" , OVAL_DATATYPE_STRING_M , sanitized_values ,
489+ NULL );
490+ } else {
491+ sanitized_value = sysctl_sanitize_single_value (sysval );
492+ if (sanitized_value == NULL ) {
493+ dE ("Failed to sanitize sysctl value" );
494+ ret = PROBE_ENOENT ;
495+ goto cleanup ;
496+ }
497+
498+ item = probe_item_create (OVAL_UNIX_SYSCTL , NULL ,
499+ "name" , OVAL_DATATYPE_SEXP , se_mib ,
500+ "value" , OVAL_DATATYPE_STRING , sanitized_value ,
501+ NULL );
502+ }
503+
388504 if (!item ) {
389505 dE ("probe_item_create() returned a null item" );
390- SEXP_free ( se_mib ) ;
391- return PROBE_ENOENT ;
506+ ret = PROBE_ENOENT ;
507+ goto cleanup ;
392508 }
393509
394510 probe_item_collect (ctx , item );
395511 }
396512
513+ cleanup :
514+ free (sanitized_value );
515+ free (sanitized_buffer );
516+ free (sanitized_values );
397517 SEXP_free (se_mib );
398- return 0 ;
518+ return ret ;
399519}
400520
401521int sysctl_probe_offline_mode_supported (void )
@@ -408,13 +528,17 @@ int sysctl_probe_main(probe_ctx *ctx, void *probe_arg)
408528 FILE * fp ;
409529 char output [LINE_MAX ];
410530 SEXP_t * name_entity , * probe_in ;
531+ oval_schema_version_t over ;
532+ int over_cmp ;
411533 int ret = 0 ;
412534 char * current_mib = NULL ;
413535 char * current_value = NULL ;
414536 size_t current_value_len = 0 ;
415537
416538 probe_in = probe_ctx_getobject (ctx );
417539 name_entity = probe_obj_getent (probe_in , "name" , 1 );
540+ over = probe_obj_get_platform_schema_version (probe_in );
541+ over_cmp = oval_schema_version_cmp (over , OVAL_SCHEMA_VERSION (5.10 ));
418542
419543 if (name_entity == NULL ) {
420544 dE ("Missing \"name\" entity in the input object" );
@@ -444,7 +568,8 @@ int sysctl_probe_main(probe_ctx *ctx, void *probe_arg)
444568 if (sysctl_parse_line (output , & mib , & sysval )) {
445569 if (current_mib != NULL ) {
446570 ret = sysctl_collect_item (ctx , name_entity , current_mib ,
447- current_value != NULL ? current_value : "" );
571+ current_value != NULL ? current_value : "" ,
572+ over_cmp );
448573 if (ret != 0 )
449574 goto cleanup ;
450575 }
@@ -477,11 +602,12 @@ int sysctl_probe_main(probe_ctx *ctx, void *probe_arg)
477602 ret = PROBE_ENOENT ;
478603 goto cleanup ;
479604 }
480- }
605+ }
481606
482607 if (current_mib != NULL )
483608 ret = sysctl_collect_item (ctx , name_entity , current_mib ,
484- current_value != NULL ? current_value : "" );
609+ current_value != NULL ? current_value : "" ,
610+ over_cmp );
485611
486612cleanup :
487613 free (current_mib );
0 commit comments