Beispiel #1
0
int compat_validate(struct selabel_handle *rec,
		    struct selabel_lookup_rec *contexts,
		    const char *path, unsigned lineno)
{
	int rc;
	char **ctx = &contexts->ctx_raw;

	if (myinvalidcon)
		rc = myinvalidcon(path, lineno, *ctx);
	else if (mycanoncon)
		rc = mycanoncon(path, lineno, ctx);
	else {
		rc = selabel_validate(rec, contexts);
		if (rc < 0) {
			if (lineno) {
				COMPAT_LOG(SELINUX_WARNING,
					    "%s: line %u has invalid context %s\n",
						path, lineno, *ctx);
			} else {
				COMPAT_LOG(SELINUX_WARNING,
					    "%s: has invalid context %s\n", path, *ctx);
			}
		}
	}

	return rc ? -1 : 0;
}
Beispiel #2
0
/*
 * Warn about duplicate specifications.
 */
static int nodups_specs(struct saved_data *data, const char *path)
{
    int rc = 0;
    unsigned int ii, jj;
    struct spec *curr_spec, *spec_arr = data->spec_arr;

    for (ii = 0; ii < data->nspec; ii++) {
        curr_spec = &spec_arr[ii];
        for (jj = ii + 1; jj < data->nspec; jj++) {
            if ((!strcmp
                    (spec_arr[jj].regex_str, curr_spec->regex_str))
                    && (!spec_arr[jj].mode || !curr_spec->mode
                        || spec_arr[jj].mode == curr_spec->mode)) {
                rc = -1;
                errno = EINVAL;
                if (strcmp
                        (spec_arr[jj].lr.ctx_raw,
                         curr_spec->lr.ctx_raw)) {
                    COMPAT_LOG
                    (SELINUX_ERROR,
                     "%s: Multiple different specifications for %s  (%s and %s).\n",
                     path, curr_spec->regex_str,
                     spec_arr[jj].lr.ctx_raw,
                     curr_spec->lr.ctx_raw);
                } else {
                    COMPAT_LOG
                    (SELINUX_ERROR,
                     "%s: Multiple same specifications for %s.\n",
                     path, curr_spec->regex_str);
                }
            }
        }
    }
    return rc;
}
Beispiel #3
0
static void stats(struct selabel_handle *rec)
{
    struct saved_data *data = (struct saved_data *)rec->data;
    unsigned int i, nspec = data->nspec;
    spec_t *spec_arr = data->spec_arr;

    for (i = 0; i < nspec; i++) {
        if (spec_arr[i].matches == 0) {
            if (spec_arr[i].type_str) {
                COMPAT_LOG(SELINUX_WARNING,
                           "Warning!  No matches for (%s, %s, %s)\n",
                           spec_arr[i].regex_str,
                           spec_arr[i].type_str,
                           spec_arr[i].lr.ctx_raw);
            } else {
                COMPAT_LOG(SELINUX_WARNING,
                           "Warning!  No matches for (%s, %s)\n",
                           spec_arr[i].regex_str,
                           spec_arr[i].lr.ctx_raw);
            }
        }
    }
}
Beispiel #4
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;
}