예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
파일: entcmp.c 프로젝트: swizzley/openscap
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;
}
예제 #4
0
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);
}