Skip to content

Commit 56232e8

Browse files
committed
fix freebsd sysctl handling
1 parent 352c072 commit 56232e8

1 file changed

Lines changed: 137 additions & 11 deletions

File tree

src/OVAL/probes/unix/sysctl_probe.c

Lines changed: 137 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
372463
static 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

401521
int 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

486612
cleanup:
487613
free(current_mib);

0 commit comments

Comments
 (0)