static int process_file(const char *path, const char *file, void *arg) { struct pfdata *pfd = (struct pfdata *) arg; int ret = 0, path_len, file_len, cur_inst = 0, fd = -1, substr_cnt, buf_size = 0, buf_used = 0, ofs = 0, buf_inc = 4096; char *whole_path = NULL, *buf = NULL; SEXP_t *next_inst = NULL; struct stat st; if (file == NULL) goto cleanup; path_len = strlen(path); file_len = strlen(file); whole_path = oscap_alloc(path_len + file_len + 2); memcpy(whole_path, path, path_len); if (whole_path[path_len - 1] != FILE_SEPARATOR) { whole_path[path_len] = FILE_SEPARATOR; ++path_len; } memcpy(whole_path + path_len, file, file_len + 1); /* * If stat() fails, don't report an error and just skip the file. * This is an expected situation, because the fts_*() functions * are called with the 'FTS_PHYSICAL' option. Normally, stumbling * upon a symlink without a target would cause fts_read() to return * the 'FTS_SLNONE' flag, but the 'FTS_PHYSICAL' option causes it * to return 'FTS_SL' and the presence of a valid target has to * be determined with stat(). */ if (stat(whole_path, &st) == -1) goto cleanup; if (!S_ISREG(st.st_mode)) goto cleanup; fd = open(whole_path, O_RDONLY); if (fd == -1) { SEXP_t *msg; msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR, "open(): '%s' %s.", whole_path, strerror(errno)); probe_cobj_add_msg(probe_ctx_getresult(pfd->ctx), msg); SEXP_free(msg); probe_cobj_set_flag(probe_ctx_getresult(pfd->ctx), SYSCHAR_FLAG_ERROR); ret = -1; goto cleanup; } do { buf_size += buf_inc; buf = oscap_realloc(buf, buf_size); ret = read(fd, buf + buf_used, buf_inc); if (ret == -1) { SEXP_t *msg; msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR, "read(): '%s' %s.", whole_path, strerror(errno)); probe_cobj_add_msg(probe_ctx_getresult(pfd->ctx), msg); SEXP_free(msg); probe_cobj_set_flag(probe_ctx_getresult(pfd->ctx), SYSCHAR_FLAG_ERROR); ret = -2; goto cleanup; } buf_used += ret; } while (ret == buf_inc); if (buf_used == buf_size) buf = realloc(buf, ++buf_size); buf[buf_used++] = '\0'; do { char **substrs; int want_instance; next_inst = SEXP_number_newi_32(cur_inst + 1); if (probe_entobj_cmp(pfd->instance_ent, next_inst) == OVAL_RESULT_TRUE) want_instance = 1; else want_instance = 0; SEXP_free(next_inst); substr_cnt = get_substrings(buf, &ofs, pfd->compiled_regex, want_instance, &substrs); if (substr_cnt > 0) { ++cur_inst; if (want_instance) { int k; SEXP_t *item; item = create_item(path, file, pfd->pattern, cur_inst, substrs, substr_cnt); probe_item_collect(pfd->ctx, item); for (k = 0; k < substr_cnt; ++k) oscap_free(substrs[k]); oscap_free(substrs); } } } while (substr_cnt > 0 && ofs < buf_used); cleanup: if (fd != -1) close(fd); oscap_free(buf); if (whole_path != NULL) oscap_free(whole_path); return ret; }
static int read_environment(SEXP_t *pid_ent, SEXP_t *name_ent, probe_ctx *ctx) { int err = 1, pid, fd; bool empty; size_t env_name_size; SEXP_t *env_name, *env_value, *item, *pid_sexp; DIR *d; struct dirent *d_entry; char *buffer, env_file[256], *null_char; ssize_t buffer_used; size_t buffer_size; d = opendir("/proc"); if (d == NULL) { dE("Can't read /proc: errno=%d, %s.\n", errno, strerror (errno)); return PROBE_EACCESS; } if ((buffer = oscap_realloc(NULL, BUFFER_SIZE)) == NULL) { dE("Can't allocate memory"); closedir(d); return PROBE_EFAULT; } buffer_size = BUFFER_SIZE; while ((d_entry = readdir(d))) { if (strspn(d_entry->d_name, "0123456789") != strlen(d_entry->d_name)) continue; pid = atoi(d_entry->d_name); pid_sexp = SEXP_number_newi_32(pid); if (probe_entobj_cmp(pid_ent, pid_sexp) != OVAL_RESULT_TRUE) { SEXP_free(pid_sexp); continue; } SEXP_free(pid_sexp); sprintf(env_file, "/proc/%d/environ", pid); if ((fd = open(env_file, O_RDONLY)) == -1) { dE("Can't open \"%s\": errno=%d, %s.\n", env_file, errno, strerror (errno)); item = probe_item_create( OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL, "pid", OVAL_DATATYPE_INTEGER, (int64_t)pid, NULL ); probe_item_setstatus(item, SYSCHAR_STATUS_ERROR); probe_item_add_msg(item, OVAL_MESSAGE_LEVEL_ERROR, "Can't open \"%s\": errno=%d, %s.", env_file, errno, strerror (errno)); probe_item_collect(ctx, item); continue; } empty = true; if ((buffer_used = read(fd, buffer, buffer_size - 1)) > 0) { empty = false; } while (! empty) { while (! (null_char = memchr(buffer, 0, buffer_used))) { ssize_t s; if ((size_t)buffer_used >= buffer_size) { buffer_size += BUFFER_SIZE; buffer = oscap_realloc(buffer, buffer_size); if (buffer == NULL) { dE("Can't allocate memory"); exit(ENOMEM); } } s = read(fd, buffer + buffer_used, buffer_size - buffer_used); if (s <= 0) { empty = true; buffer[buffer_used++] = 0; } else { buffer_used += s; } } do { char *eq_char = strchr(buffer, '='); if (eq_char == NULL) { /* strange but possible: * $ strings /proc/1218/environ /dev/input/event0 /dev/input/event1 /dev/input/event4 /dev/input/event3 */ buffer_used -= null_char + 1 - buffer; memmove(buffer, null_char + 1, buffer_used); continue; } env_name_size = eq_char - buffer; env_name = SEXP_string_new(buffer, env_name_size); env_value = SEXP_string_newf("%s", buffer + env_name_size + 1); if (probe_entobj_cmp(name_ent, env_name) == OVAL_RESULT_TRUE) { item = probe_item_create( OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL, "pid", OVAL_DATATYPE_INTEGER, (int64_t)pid, "name", OVAL_DATATYPE_SEXP, env_name, "value", OVAL_DATATYPE_SEXP, env_value, NULL); probe_item_collect(ctx, item); err = 0; } SEXP_free(env_name); SEXP_free(env_value); buffer_used -= null_char + 1 - buffer; memmove(buffer, null_char + 1, buffer_used); } while ((null_char = memchr(buffer, 0, buffer_used))); } close(fd); } closedir(d); oscap_free(buffer); if (err) { SEXP_t *msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR, "Can't find process with requested PID."); probe_cobj_add_msg(probe_ctx_getresult(ctx), msg); SEXP_free(msg); err = 0; } return err; }
static oval_result_t probe_ent_cmp(SEXP_t * ent, SEXP_t * val2) { oval_operation_t op; oval_datatype_t dtype; SEXP_t *stmp, *val1, *vals, *res_lst, *r0; int val_cnt, is_var; oval_check_t ochk; oval_result_t ores, result; ores = OVAL_RESULT_ERROR; result = OVAL_RESULT_ERROR; vals = NULL; val_cnt = probe_ent_getvals(ent, &vals); if (probe_ent_attrexists(ent, "var_ref")) { is_var = 1; } else { if (val_cnt != 1) { SEXP_free(vals); return OVAL_RESULT_ERROR; } is_var = 0; } dtype = probe_ent_getdatatype(ent); stmp = probe_ent_getattrval(ent, "operation"); if (stmp == NULL) op = OVAL_OPERATION_EQUALS; else op = SEXP_number_geti_32(stmp); SEXP_free(stmp); res_lst = SEXP_list_new(NULL); SEXP_list_foreach(val1, vals) { if (SEXP_typeof(val1) != SEXP_typeof(val2)) { dI("Types of values to compare don't match: val1: %d, val2: %d\n", SEXP_typeof(val1), SEXP_typeof(val2)); SEXP_free(vals); SEXP_free(val1); SEXP_free(res_lst); return OVAL_RESULT_ERROR; } ores = probe_ent_cmp_single(val1, dtype, val2, op); SEXP_list_add(res_lst, r0 = SEXP_number_newi_32(ores)); SEXP_free(r0); } if (is_var) { stmp = probe_ent_getattrval(ent, "var_check"); if (stmp == NULL) { ochk = OVAL_CHECK_ALL; } else { ochk = SEXP_number_geti_32(stmp); SEXP_free(stmp); } result = probe_ent_result_bychk(res_lst, ochk); } else { result = ores; } SEXP_free(res_lst); SEXP_free(vals); return result; }
int main (void) { SEXP_t *s_exp; int8_t i8 = -1; uint8_t u8 = 1; int16_t i16 = -32000; uint16_t u16 = 65000; int32_t i32 = -100000; uint32_t u32 = 100000; int64_t i64 = -1 * (1 << 30); uint64_t u64 = (uint64_t)1 << 48; double f = 123.456; s_exp = SEXP_number_newi_8 (i8); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newu_8 (u8); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newi_16 (i16); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newu_16 (u16); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newi_32 (i32); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newu_32 (u32); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newi_64 (i64); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newu_64 (u64); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newf (f); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); return (0); }