Example #1
0
void nano_sem_take_wait(struct nano_sem *sem)
{
	static void (*func[3])(struct nano_sem *sem) = {
		NULL, nano_fiber_sem_take_wait, nano_task_sem_take_wait
	};
	func[context_type_get()](sem);
}
Example #2
0
void nano_sem_give(struct nano_sem *sem)
{
	static void (*func[3])(struct nano_sem *sem) = {
		nano_isr_sem_give, nano_fiber_sem_give, nano_task_sem_give
	};
	func[context_type_get()](sem);
}
Example #3
0
static int parse_components(context_t con, char **components) {
	components[COLOR_USER] = (char *)context_user_get(con);
	components[COLOR_ROLE] = (char *)context_role_get(con);
	components[COLOR_TYPE] = (char *)context_type_get(con);
	components[COLOR_RANGE] = (char *)context_range_get(con);

	return 0;
}
Example #4
0
/*
  This function takes a path and a mode, it calls computecon to get the
  label of the path object if the current process created it, then it calls
  matchpathcon to get the default type for the object.  It substitutes the
  default type into label.  It tells the SELinux Kernel to label all new file
  system objects created by the current process with this label.

  Returns -1 on failure.  errno will be set appropriately.
*/
int
defaultcon (char const *path, mode_t mode)
{
  int rc = -1;
  char *scon = NULL;
  char *tcon = NULL;
  context_t scontext = 0, tcontext = 0;
  const char *contype;
  char *constr;
  char *newpath = NULL;

  if (! IS_ABSOLUTE_FILE_NAME (path))
    {
      /* Generate absolute path as required by subsequent matchpathcon(),
         with libselinux < 2.1.5 2011-0826.  */
      newpath = canonicalize_filename_mode (path, CAN_MISSING);
      if (! newpath)
        error (EXIT_FAILURE, errno, _("error canonicalizing %s"),
               quote (path));
      path = newpath;
    }

  if (matchpathcon (path, mode, &scon) < 0)
    {
      /* "No such file or directory" is a confusing error,
         when processing files, when in fact it was the
         associated default context that was not found.
         Therefore map the error to something more appropriate
         to the context in which we're using matchpathcon().  */
      if (errno == ENOENT)
        errno = ENODATA;
      goto quit;
    }
  if (computecon (path, mode, &tcon) < 0)
    goto quit;
  if (!(scontext = context_new (scon)))
    goto quit;
  if (!(tcontext = context_new (tcon)))
    goto quit;

  if (!(contype = context_type_get (scontext)))
    goto quit;
  if (context_type_set (tcontext, contype))
    goto quit;
  if (!(constr = context_str (tcontext)))
    goto quit;

  rc = setfscreatecon (constr);

quit:
  context_free (scontext);
  context_free (tcontext);
  freecon (scon);
  freecon (tcon);
  free (newpath);
  return rc;
}
Example #5
0
static void context_sem_give(struct nano_sem *chan)
{
	switch (context_type_get()) {
	case NANO_CTX_FIBER:
		nano_fiber_sem_give(chan);
		break;
	case NANO_CTX_TASK:
		nano_task_sem_give(chan);
		break;
	case NANO_CTX_ISR:
	default:
		/* Invalid context type */
		break;
	}
}
Example #6
0
static char *get_selinux_label(int pid) {
#ifdef HAVE_SELINUX_SELINUX_H
	char *selinux_label;
	security_context_t pid_context;
	context_t context;

	if (getpidcon(pid, &pid_context) == -1) {
		/* error getting pid selinux context */
		dW("Can't get selinux context for process %d\n", pid);
		return NULL;
	}
	context = context_new(pid_context);
	selinux_label = strdup(context_type_get(context));
	context_free(context);
	freecon(pid_context);
	return selinux_label;

#else
	return NULL;
#endif /* HAVE_SELINUX_SELINUX_H */
}
static int find_partialcon(security_context_t * list,
			   unsigned int nreach, char *part)
{
	const char *conrole, *contype;
	char *partrole, *parttype, *ptr;
	context_t con;
	unsigned int i;

	partrole = part;
	ptr = part;
	while (*ptr && !isspace(*ptr) && *ptr != ':')
		ptr++;
	if (*ptr != ':')
		return -1;
	*ptr++ = 0;
	parttype = ptr;
	while (*ptr && !isspace(*ptr) && *ptr != ':')
		ptr++;
	*ptr = 0;

	for (i = 0; i < nreach; i++) {
		con = context_new(list[i]);
		if (!con)
			return -1;
		conrole = context_role_get(con);
		contype = context_type_get(con);
		if (!conrole || !contype) {
			context_free(con);
			return -1;
		}
		if (!strcmp(conrole, partrole) && !strcmp(contype, parttype)) {
			context_free(con);
			return i;
		}
		context_free(con);
	}

	return -1;
}
Example #8
0
static void disp_con(security_context_t scon)
{
	context_t con = NULL;

	if (!*scon) {		/* --self-exec and --self-fs etc. */
		if (opts->disp_user)
			disp__con_val("user", NULL);
		if (opts->disp_role)
			disp__con_val("role", NULL);
		if (opts->disp_type)
			disp__con_val("type", NULL);
		if (opts->disp_sen)
			disp__con_val("sensitivity", NULL);
		if (opts->disp_clr)
			disp__con_val("clearance", NULL);
		if (opts->disp_mlsr)
			disp__con_val("mls-range", NULL);
		return;
	}

	if (!(con = context_new(scon)))
		errx(EXIT_FAILURE, "Couldn't create context from: %s", scon);

	if (opts->disp_user)
		disp__con_val("user", context_user_get(con));
	if (opts->disp_role)
		disp__con_val("role", context_role_get(con));
	if (opts->disp_type)
		disp__con_val("type", context_type_get(con));
	if (opts->disp_sen) {
		const char *val = NULL;
		char *tmp = NULL;

		val = context_range_get(con);
		if (!val)
			val = "";	/* targeted has no "level" etc.,
					   any errors should happen at context_new() time */

		tmp = strdup(val);
		if (!tmp)
			errx(EXIT_FAILURE, "Couldn't create context from: %s",
			     scon);
		if (strchr(tmp, '-'))
			*strchr(tmp, '-') = 0;

		disp__con_val("sensitivity", tmp);

		free(tmp);
	}
	if (opts->disp_clr) {
		const char *val = NULL;
		char *tmp = NULL;

		val = context_range_get(con);
		if (!val)
			val = "";	/* targeted has no "level" etc.,
					   any errors should happen at context_new() time */

		tmp = strdup(val);
		if (!tmp)
			errx(EXIT_FAILURE, "Couldn't create context from: %s",
			     scon);
		if (strchr(tmp, '-'))
			disp__con_val("clearance", strchr(tmp, '-') + 1);
		else
			disp__con_val("clearance", tmp);

		free(tmp);
	}

	if (opts->disp_mlsr)
		disp__con_val("mls-range", context_range_get(con));

	context_free(con);
}
Example #9
0
/*
  This function takes a PATH of an existing file system object, and a LOCAL
  boolean that indicates whether the function should set the object's label
  to the default for the local process, or one using system wide settings.
  If LOCAL == true, it will ask the SELinux Kernel what the default label
  for all objects created should be and then sets the label on the object.
  Otherwise it calls matchpathcon on the object to ask the system what the
  default label should be, extracts the type field and then modifies the file
  system object.  Note only the type field is updated, thus preserving MLS
  levels and user identity etc. of the PATH.

  Returns -1 on failure.  errno will be set appropriately.
*/
static int
restorecon_private (char const *path, bool local)
{
  int rc = -1;
  struct stat sb;
  char *scon = NULL;
  char *tcon = NULL;
  context_t scontext = 0, tcontext = 0;
  const char *contype;
  char *constr;
  int fd;

  if (local)
    {
      if (getfscreatecon (&tcon) < 0)
        return rc;
      if (!tcon)
        {
          errno = ENODATA;
          return rc;
        }
      rc = lsetfilecon (path, tcon);
      freecon (tcon);
      return rc;
    }

  fd = open (path, O_RDONLY | O_NOFOLLOW);
  if (fd == -1 && (errno != ELOOP))
    goto quit;

  if (fd != -1)
    {
      if (fstat (fd, &sb) < 0)
        goto quit;
    }
  else
    {
      if (lstat (path, &sb) < 0)
        goto quit;
    }

  if (matchpathcon (path, sb.st_mode, &scon) < 0)
    {
      /* "No such file or directory" is a confusing error,
         when processing files, when in fact it was the
         associated default context that was not found.
         Therefore map the error to something more appropriate
         to the context in which we're using matchpathcon().  */
      if (errno == ENOENT)
        errno = ENODATA;
      goto quit;
    }
  if (!(scontext = context_new (scon)))
    goto quit;

  if (fd != -1)
    {
      if (fgetfilecon (fd, &tcon) < 0)
        goto quit;
    }
  else
    {
      if (lgetfilecon (path, &tcon) < 0)
        goto quit;
    }

  if (!(tcontext = context_new (tcon)))
    goto quit;

  if (!(contype = context_type_get (scontext)))
    goto quit;
  if (context_type_set (tcontext, contype))
    goto quit;
  if (!(constr = context_str (tcontext)))
    goto quit;

  if (fd != -1)
    rc = fsetfilecon (fd, constr);
  else
    rc = lsetfilecon (path, constr);

quit:
  if (fd != -1)
    close (fd);
  context_free (scontext);
  context_free (tcontext);
  freecon (scon);
  freecon (tcon);
  return rc;
}
Example #10
0
/*
 * do_set_domain
 *   It tries to replace the domain/range of the current context.
 */
static int
do_set_domain(security_context_t old_context, char *domain, server_rec *s)
{
    security_context_t  new_context;
    security_context_t  raw_context;
    context_t           context;
    char               *range;

    /*
     * Compute the new security context
     */
    context = context_new(old_context);
    if (!context) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: context_new(\"%s\") failed",
                     old_context);
        return -1;
    }

    range = strchr(domain, ':');
    if (range)
        *range++ = '\0';

    if (domain && strcmp(domain, "*") != 0)
        context_type_set(context, domain);
    if (range  && strcmp(range, "*") != 0)
        context_range_set(context, range);

    if (range)
        *--range = ':';     /* fixup */

    new_context = context_str(context);
    if (!new_context) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: context_str(\"%s:%s:%s:%s\") failed",
                     context_user_get(context),
                     context_role_get(context),
                     context_type_get(context),
                     context_range_get(context));
        context_free(context);
        return -1;
    }

    /*
     * If old_context == new_context, we don't need to do anything
     */
    if (selinux_trans_to_raw_context(new_context, &raw_context) < 0) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: selinux_trans_to_raw_context(\"%s\") failed",
                     new_context);
        context_free(context);
        return -1;
    }
    context_free(context);

    if (!strcmp(old_context, raw_context)) {
        freecon(raw_context);
        return 1;
    }

    if (setcon_raw(raw_context) < 0) {
        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
                     "SELinux: setcon_raw(\"%s\") failed",
                     raw_context);
        freecon(raw_context);
        return -1;
    }

    freecon(raw_context);

    return 0;
}
Example #11
0
static bool
testSELinuxCheckCon(context_t con,
                    const char *user,
                    const char *role,
                    const char *type,
                    int sensMin,
                    int sensMax ATTRIBUTE_UNUSED,
                    int catMin,
                    int catMax)
{
    const char *range;
    char *tmp;
    int gotSens;
    int gotCatOne;
    int gotCatTwo;

    if (STRNEQ(context_user_get(con), user)) {
        fprintf(stderr, "Expect user %s got %s\n",
                user, context_user_get(con));
        return false;
    }
    if (STRNEQ(context_role_get(con), role)) {
        fprintf(stderr, "Expect role %s got %s\n",
                role, context_role_get(con));
        return false;
    }
    if (STRNEQ(context_type_get(con), type)) {
        fprintf(stderr, "Expect type %s got %s\n",
                type, context_type_get(con));
        return false;
    }

    range = context_range_get(con);
    if (range[0] != 's') {
        fprintf(stderr, "Malformed range %s, cannot find sensitivity\n",
                range);
        return false;
    }
    if (virStrToLong_i(range + 1, &tmp, 10, &gotSens) < 0 ||
        !tmp) {
        fprintf(stderr, "Malformed range %s, cannot parse sensitivity\n",
                range + 1);
        return false;
    }
    if (*tmp != ':') {
        fprintf(stderr, "Malformed range %s, too many sensitivity values\n",
                tmp);
        return false;
    }
    tmp++;
    if (*tmp != 'c') {
        fprintf(stderr, "Malformed range %s, cannot find first category\n",
                tmp);
        return false;
    }
    tmp++;
    if (virStrToLong_i(tmp, &tmp, 10, &gotCatOne) < 0) {
        fprintf(stderr, "Malformed range %s, cannot parse category one\n",
                tmp);
        return false;
    }
    if (tmp && *tmp == ',')
        tmp++;
    if (tmp && *tmp == 'c') {
        tmp++;
        if (virStrToLong_i(tmp, &tmp, 10, &gotCatTwo) < 0) {
            fprintf(stderr, "Malformed range %s, cannot parse category two\n",
                    tmp);
            return false;
        }
        if (*tmp != '\0') {
            fprintf(stderr, "Malformed range %s, junk after second category\n",
                    tmp);
            return false;
        }
        if (gotCatOne == gotCatTwo) {
            fprintf(stderr, "Saw category pair %d,%d where cats were equal\n",
                    gotCatOne, gotCatTwo);
            return false;
        }
    } else {
        gotCatTwo = gotCatOne;
    }

    if (gotSens != sensMin) {
        fprintf(stderr, "Sensitivity %d is not equal to min %d\n",
                gotSens, sensMin);
        return false;
    }
    if (gotCatOne < catMin ||
        gotCatOne > catMax) {
        fprintf(stderr, "Category one %d is out of range %d-%d\n",
                gotCatTwo, catMin, catMax);
        return false;
    }
    if (gotCatTwo < catMin ||
        gotCatTwo > catMax) {
        fprintf(stderr, "Category two %d is out of range %d-%d\n",
                gotCatTwo, catMin, catMax);
        return false;
    }

    if (gotCatOne > gotCatTwo) {
        fprintf(stderr, "Category one %d is greater than category two %d\n",
                gotCatOne, gotCatTwo);
        return false;
    }

    return true;
}
Example #12
0
void selinux_setup(char **argv)
{
    char *new_context = NULL;
    char *curr_context = NULL;
    context_t curr_con;
    char *curr_t = NULL;
    char *run_init_t = NULL;

    /* Return, if selinux is disabled. */
    if (is_selinux_enabled() < 1) {
        return;
    }

    if (read_context_file(RUN_INIT_FILE, &run_init_t) != 0) {
        /* assume a reasonable default, rather than bailing out */
        run_init_t = xstrdup("run_init_t");
        ewarn("Assuming SELinux run_init type is %s", run_init_t);
    }

    /* Get our current context. */
    if (getcon(&curr_context) < 0) {
        if (errno == ENOENT) {
            /* should only hit this if proc is not mounted.  this
             * happens on Gentoo right after init starts, when
             * the init script processing starts.
             */
            goto out;
        } else {
            perror("getcon");
            exit(1);
        }
    }

    /* extract the type from the context */
    curr_con = context_new(curr_context);
    if (!curr_con) {
        free(curr_context);
        goto out;
    }

    curr_t = context_type_get(curr_con);
    if (!curr_t) {
        context_free(curr_con);
        free(curr_context);
        goto out;
    }

    curr_t = xstrdup(curr_t);
    /* dont need them anymore so free() now */
    context_free(curr_con);
    free(curr_context);

    /* if we are not in the run_init domain, we should not do anything */
    if (strncmp(run_init_t, curr_t, strlen(run_init_t)) != 0) {
        goto out;
    }

    free(curr_t);
    free(run_init_t);

    if (check_auth() != 0) {
        eerrorx("Authentication failed.");
    }

    /* Get the context for the script to be run in. */
    if (read_context_file(INITRC_FILE, &new_context) != 0) {
        /* assume a reasonable default, rather than bailing out */
        new_context = xstrdup("system_u:system_r:initrc_t");
        ewarn("Assuming SELinux initrc context is %s", new_context);
    }

    /* Set the new context */
    if (setexeccon(new_context) < 0) {
        eerrorx("Could not set SELinux exec context to %s.", new_context);
    }

    free(new_context);

    /*
     * exec will recycle ptys so try and use open_init_pty if it exists
     * which will open the pty with initrc_devpts_t, if it doesnt exist,
     * fall back to plain exec
     */
    if (!access("/usr/sbin/open_init_pty", X_OK)) {
        if (execvp("/usr/sbin/open_init_pty", argv)) {
            perror("execvp");
            exit(-1);
        }
    } else if (execvp(argv[1], argv + 1)) {
        perror("execvp");
        exit(-1);
    }

out:
    free(run_init_t);
    free(curr_t);
}
Example #13
0
static int get_context_order(FILE * fp,
			     security_context_t fromcon,
			     security_context_t * reachable,
			     unsigned int nreach,
			     unsigned int *ordering, unsigned int *nordered)
{
	char *start, *end = NULL;
	char *line = NULL;
	size_t line_len = 0;
	ssize_t len;
	int found = 0;
	const char *fromrole, *fromtype;
	char *linerole, *linetype;
	unsigned int i;
	context_t con;
	int rc;

	errno = -EINVAL;

	/* Extract the role and type of the fromcon for matching.
	   User identity and MLS range can be variable. */
	con = context_new(fromcon);
	if (!con)
		return -1;
	fromrole = context_role_get(con);
	fromtype = context_type_get(con);
	if (!fromrole || !fromtype) {
		context_free(con);
		return -1;
	}

	while ((len = getline(&line, &line_len, fp)) > 0) {
		if (line[len - 1] == '\n')
			line[len - 1] = 0;

		/* Skip leading whitespace. */
		start = line;
		while (*start && isspace(*start))
			start++;
		if (!(*start))
			continue;

		/* Find the end of the (partial) fromcon in the line. */
		end = start;
		while (*end && !isspace(*end))
			end++;
		if (!(*end))
			continue;

		/* Check for a match. */
		linerole = start;
		while (*start && !isspace(*start) && *start != ':')
			start++;
		if (*start != ':')
			continue;
		*start = 0;
		linetype = ++start;
		while (*start && !isspace(*start) && *start != ':')
			start++;
		if (!(*start))
			continue;
		*start = 0;
		if (!strcmp(fromrole, linerole) && !strcmp(fromtype, linetype)) {
			found = 1;
			break;
		}
	}

	if (!found) {
		errno = ENOENT;
		rc = -1;
		goto out;
	}

	start = ++end;
	while (*start) {
		/* Skip leading whitespace */
		while (*start && isspace(*start))
			start++;
		if (!(*start))
			break;

		/* Find the end of this partial context. */
		end = start;
		while (*end && !isspace(*end))
			end++;
		if (*end)
			*end++ = 0;

		/* Check for a match in the reachable list. */
		rc = find_partialcon(reachable, nreach, start);
		if (rc < 0) {
			/* No match, skip it. */
			start = end;
			continue;
		}

		/* If a match is found and the entry is not already ordered
		   (e.g. due to prior match in prior config file), then set
		   the ordering for it. */
		i = rc;
		if (ordering[i] == nreach)
			ordering[i] = (*nordered)++;
		start = end;
	}

	rc = 0;

      out:
	context_free(con);
	free(line);
	return rc;
}