コード例 #1
0
static int process_line(struct selabel_handle *rec,
                        const char *path, const char *prefix,
                        char *line_buf, int pass, unsigned lineno)
{
    int items, len;
    char *buf_p, *regex, *type, *context;
    struct saved_data *data = (struct saved_data *)rec->data;
    spec_t *spec_arr = data->spec_arr;
    unsigned int nspec = data->nspec;

    len = strlen(line_buf);
    if (line_buf[len - 1] == '\n')
        line_buf[len - 1] = 0;
    buf_p = line_buf;
    while (isspace(*buf_p))
        buf_p++;
    /* Skip comment lines and empty lines. */
    if (*buf_p == '#' || *buf_p == 0)
        return 0;
    items = sscanf(line_buf, "%as %as %as", &regex, &type, &context);
    if (items < 2) {
        COMPAT_LOG(SELINUX_WARNING,
                   "%s:  line %d is missing fields, skipping\n", path,
                   lineno);
        if (items == 1)
            free(regex);
        return 0;
    } else if (items == 2) {
        /* The type field is optional. */
        free(context);
        context = type;
        type = 0;
    }

    len = get_stem_from_spec(regex);
    if (len && prefix && strncmp(prefix, regex, len)) {
        /* Stem of regex does not match requested prefix, discard. */
        free(regex);
        free(type);
        free(context);
        return 0;
    }

    if (pass == 1) {
        /* On the second pass, process and store the specification in spec. */
        char *errbuf = NULL;
        spec_arr[nspec].stem_id = find_stem_from_spec(data, regex);
        spec_arr[nspec].regex_str = regex;
        if (rec->validating && compile_regex(data, &spec_arr[nspec], &errbuf)) {
            COMPAT_LOG(SELINUX_WARNING,
                       "%s:  line %d has invalid regex %s:  %s\n",
                       path, lineno, regex,
                       (errbuf ? errbuf : "out of memory"));
        }

        /* Convert the type string to a mode format */
        spec_arr[nspec].type_str = type;
        spec_arr[nspec].mode = 0;
        if (!type)
            goto skip_type;
        len = strlen(type);
        if (type[0] != '-' || len != 2) {
            COMPAT_LOG(SELINUX_WARNING,
                       "%s:  line %d has invalid file type %s\n",
                       path, lineno, type);
            return 0;
        }
        switch (type[1]) {
        case 'b':
            spec_arr[nspec].mode = S_IFBLK;
            break;
        case 'c':
            spec_arr[nspec].mode = S_IFCHR;
            break;
        case 'd':
            spec_arr[nspec].mode = S_IFDIR;
            break;
        case 'p':
            spec_arr[nspec].mode = S_IFIFO;
            break;
        case 'l':
            spec_arr[nspec].mode = S_IFLNK;
            break;
        case 's':
            spec_arr[nspec].mode = S_IFSOCK;
            break;
        case '-':
            spec_arr[nspec].mode = S_IFREG;
            break;
        default:
            COMPAT_LOG(SELINUX_WARNING,
                       "%s:  line %d has invalid file type %s\n",
                       path, lineno, type);
            return 0;
        }

skip_type:
        spec_arr[nspec].lr.ctx_raw = context;

        /* Determine if specification has
         * any meta characters in the RE */
        spec_hasMetaChars(&spec_arr[nspec]);

        if (strcmp(context, "<<none>>") && rec->validating)
            compat_validate(rec, &spec_arr[nspec].lr, path, lineno);
    }

    data->nspec = ++nspec;
    if (pass == 0) {
        free(regex);
        if (type)
            free(type);
        free(context);
    }
    return 0;
}
コード例 #2
0
static int process_file(struct saved_data *data, const char *filename)
{
	struct spec *spec;
	unsigned int line_num;
	char *line_buf = NULL;
	size_t line_len;
	ssize_t len;
	FILE *context_file;

	context_file = fopen(filename, "r");
	if (!context_file) {
		fprintf(stderr, "Error opening %s: %s\n", filename, strerror(errno));
		return -1;
	}

	line_num = 0;
	while ((len = getline(&line_buf, &line_len, context_file)) != -1) {
		char *context;
		char *mode;
		char *regex;
		char *cp, *anchored_regex;
		char *buf_p;
		pcre *re;
		pcre_extra *sd;
		const char *err;
		int items, erroff, rc;
		size_t regex_len;
		int32_t stem_id;

		len = strlen(line_buf);
		if (line_buf[len - 1] == '\n')
			line_buf[len - 1] = 0;
		buf_p = line_buf;
		while (isspace(*buf_p))
			buf_p++;
		/* Skip comment lines and empty lines. */
		if (*buf_p == '#' || *buf_p == 0)
			continue;

		items = sscanf(line_buf, "%ms %ms %ms", &regex, &mode, &context);
		if (items < 2 || items > 3) {
			fprintf(stderr, "invalid entry, skipping:%s", line_buf);
			continue;
		}

		if (items == 2) {
			context = mode;
			mode = NULL;
		}

		rc = grow_specs(data);
		if (rc) {
			fprintf(stderr, "grow_specs failed: %s\n", strerror(errno));
			return rc;
		}

		spec = &data->spec_arr[data->nspec];

		spec->lr.ctx_raw = context;
		spec->mode = string_to_mode(mode);
		if (spec->mode == -1) {
			fprintf(stderr, "%s: line %d has invalid file type %s\n",
				regex, line_num + 1, mode);
			spec->mode = 0;
		}
		free(mode);
		spec->regex_str = regex;

		stem_id = find_stem_from_spec(data, regex);
		spec->stem_id = stem_id;
		/* skip past the fixed stem part */
		if (stem_id != -1)
			regex += data->stem_arr[stem_id].len;

		regex_len = strlen(regex);
		cp = anchored_regex = malloc(regex_len + 3);
		if (!cp) {
			fprintf(stderr, "Malloc Failed: %s\n", strerror(errno));
			return -1;
		}
		*cp++ = '^';
		memcpy(cp, regex, regex_len);
		cp += regex_len;
		*cp++ = '$';
		*cp = '\0';

		spec_hasMetaChars(spec);

		re = pcre_compile(anchored_regex, 0, &err, &erroff, NULL);
		if (!re) {
			fprintf(stderr, "PCRE compilation failed for %s at offset %d: %s\n", anchored_regex, erroff, err);
			return -1;
		}
		spec->regex = re;

		sd = pcre_study(re, 0, &err);
		if (!sd) {
			fprintf(stderr, "PCRE study failed for %s: %s\n", anchored_regex, err);
			return -1;
		}
		free(anchored_regex);
		spec->sd = sd;

		line_num++;
		data->nspec++;
	}

	free(line_buf);
	fclose(context_file);

	return 0;
}