Esempio n. 1
0
static void
privupdate_self(void)
{
	int set;

	if (mac_aware) {
		if (setpflags(NET_MAC_AWARE, 1) != 0)
			fatal("setpflags(NET_MAC_AWARE)");
		if (setpflags(NET_MAC_AWARE_INHERIT, 1) != 0)
			fatal("setpflags(NET_MAC_AWARE_INHERIT)");
	}
	if (pfexec) {
		if (setpflags(PRIV_PFEXEC, 1) != 0)
			fatal("setpflags(PRIV_PFEXEC)");
	}

	if (sets != NULL) {
		priv_set_t *target = priv_allocset();

		if (target == NULL)
			fatal("priv_allocet");

		set = priv_getsetbyname(PRIV_INHERITABLE);
		if (rem[set] != NULL || add[set] != NULL ||
		    assign[set] != NULL) {
			(void) getppriv(PRIV_INHERITABLE, target);
			if (rem[set] != NULL)
				priv_intersect(rem[set], target);
			if (add[set] != NULL)
				priv_union(add[set], target);
			if (assign[set] != NULL)
				priv_copyset(assign[set], target);
			if (setppriv(PRIV_SET, PRIV_INHERITABLE, target) != 0)
				fatal("setppriv(Inheritable)");
		}
		set = priv_getsetbyname(PRIV_LIMIT);
		if (rem[set] != NULL || add[set] != NULL ||
		    assign[set] != NULL) {
			(void) getppriv(PRIV_LIMIT, target);
			if (rem[set] != NULL)
				priv_intersect(rem[set], target);
			if (add[set] != NULL)
				priv_union(add[set], target);
			if (assign[set] != NULL)
				priv_copyset(assign[set], target);
			if (setppriv(PRIV_SET, PRIV_LIMIT, target) != 0)
				fatal("setppriv(Limit)");
		}
		priv_freeset(target);
	}

	if (Doff || Don)
		(void) setpflags(PRIV_DEBUG, Don ? 1 : 0);
	if (xpol)
		(void) setpflags(PRIV_XPOLICY, 1);
	if (pfexec)
		(void) setpflags(PRIV_PFEXEC, 1);
}
Esempio n. 2
0
static void
vjs_waive(enum jail_gen_e jge)
{
	priv_set_t *effective, *inheritable, *permitted, *limited;

	if (!(effective = priv_allocset()) ||
	    !(inheritable = priv_allocset()) ||
	    !(permitted = priv_allocset()) ||
	    !(limited = priv_allocset())) {
		MGT_complain(C_SECURITY,
		    "Solaris Jail warning: "
		    " vjs_waive - priv_allocset failed: errno=%d (%s)",
		    errno, strerror(errno));
		return;
	}

	/*
	 * inheritable and effective are distinct sets
	 * effective is a subset of permitted
	 * limit is the union of all
	 */

	priv_emptyset(inheritable);
	vjs_add_inheritable(inheritable, jge);

	priv_emptyset(effective);
	vjs_add_effective(effective, jge);

	priv_copyset(effective, permitted);
	vjs_add_permitted(permitted, jge);

	priv_copyset(inheritable, limited);
	priv_union(permitted, limited);
	/*
	 * invert the sets and clear privileges such that setppriv will always
	 * succeed
	 */
	priv_inverse(limited);
	priv_inverse(permitted);
	priv_inverse(effective);
	priv_inverse(inheritable);

	AZ(setppriv(PRIV_OFF, PRIV_LIMIT, limited));
	AZ(setppriv(PRIV_OFF, PRIV_PERMITTED, permitted));
	AZ(setppriv(PRIV_OFF, PRIV_EFFECTIVE, effective));
	AZ(setppriv(PRIV_OFF, PRIV_INHERITABLE, inheritable));

	priv_freeset(limited);
	priv_freeset(permitted);
	priv_freeset(effective);
	priv_freeset(inheritable);
}
static void
mgt_sandbox_solaris_waive(enum sandbox_e who)
{
	priv_set_t *effective, *inheritable, *permitted;

	if (!(effective = priv_allocset()) ||
	    !(inheritable = priv_allocset()) ||
	    !(permitted = priv_allocset())) {
		REPORT(LOG_ERR,
		    "Sandbox warning: "
		    " mgt_sandbox_waive - priv_allocset failed: errno=%d (%s)",
		    errno, strerror(errno));
		return;
	}

	/*
	 * simple scheme:
	 *     (inheritable subset-of effective) subset-of permitted
	 */

	priv_emptyset(inheritable);
	mgt_sandbox_solaris_add_inheritable(inheritable, who);

	priv_copyset(inheritable, effective);
	mgt_sandbox_solaris_add_effective(effective, who);

	priv_copyset(effective, permitted);
	mgt_sandbox_solaris_add_permitted(permitted, who);

	/*
	 * invert the sets and clear privileges such that setppriv will always
	 * succeed
	 */
	priv_inverse(inheritable);
	priv_inverse(effective);
	priv_inverse(permitted);

	AZ(setppriv(PRIV_OFF, PRIV_LIMIT, permitted));
	AZ(setppriv(PRIV_OFF, PRIV_PERMITTED, permitted));
	AZ(setppriv(PRIV_OFF, PRIV_EFFECTIVE, effective));
	AZ(setppriv(PRIV_OFF, PRIV_INHERITABLE, inheritable));

	priv_freeset(inheritable);
	priv_freeset(effective);
	priv_freeset(permitted);
}
void
mgt_sandbox_solaris_fini(void)
{
	priv_set_t *effective, *inheritable, *permitted;

	if (!(effective = priv_allocset()) ||
	    !(inheritable = priv_allocset()) ||
	    !(permitted = priv_allocset())) {
		REPORT(LOG_ERR,
		    "Child start warning: mgt_sandbox_waive - priv_allocset failed: errno=%d (%s)",
		    errno, strerror(errno));
		return;
	}

	priv_emptyset(inheritable);

	priv_emptyset(effective);
	mgt_sandbox_solaris_add_effective(effective);

	priv_copyset(effective, permitted);
	mgt_sandbox_solaris_add_permitted(permitted);

	/* 
	 * invert the sets and clear privileges such that setppriv will always
	 * succeed
	 */
	priv_inverse(inheritable);
	priv_inverse(effective);
	priv_inverse(permitted);

#define SETPPRIV(which, set)						\
	if (setppriv(PRIV_OFF, which, set))				\
		REPORT(LOG_ERR,						\
		    "Child start warning: Waiving privileges failed on %s: errno=%d (%s)", \
		    #which, errno, strerror(errno));

	SETPPRIV(PRIV_INHERITABLE, inheritable);
	SETPPRIV(PRIV_EFFECTIVE, effective);
	SETPPRIV(PRIV_PERMITTED, permitted);
	SETPPRIV(PRIV_LIMIT, permitted);
#undef SETPPRIV

	priv_freeset(inheritable);
	priv_freeset(effective);
}
static int privileges_drop_first(apr_pool_t *pool, server_rec *s)
{
    /* We need to set privileges before mod_unixd,
     * 'cos otherwise setuid will wipe our privilege to do so
     */
    priv_cfg *spcfg;
    server_rec *sp;
    priv_set_t *ppriv = priv_allocset();

    /* compute ppriv from the union of all the vhosts plus setid */
    priv_copyset(priv_setid, ppriv);
    for (sp = s; sp != NULL; sp=sp->next) {
        spcfg = ap_get_module_config(sp->module_config, &privileges_module);
        priv_union(spcfg->priv, ppriv);
    }
    PDROP_CHECK(setppriv(PRIV_SET, PRIV_PERMITTED, ppriv))
    PDROP_CHECK(setppriv(PRIV_SET, PRIV_EFFECTIVE, ppriv))
    priv_freeset(ppriv);

    return OK;
}
Esempio n. 6
0
/**
 * Grabs extra non-root capabilities / privileges that we might require.
 *
 * This is currently only used for being able to do ICMP from the NAT engine.
 *
 * @note We still have root privileges at the time of this call.
 */
static void supR3HardenedMainGrabCapabilites(void)
{
# if defined(RT_OS_LINUX)
    /*
     * We are about to drop all our privileges. Remove all capabilities but
     * keep the cap_net_raw capability for ICMP sockets for the NAT stack.
     */
    if (g_uCaps != 0)
    {
#  ifdef USE_LIB_PCAP
        /* XXX cap_net_bind_service */
        if (!cap_set_proc(cap_from_text("all-eip cap_net_raw+ep")))
            prctl(PR_SET_KEEPCAPS, 1 /*keep=*/, 0, 0, 0);
        prctl(PR_SET_DUMPABLE, 1 /*dump*/, 0, 0, 0);
#  else
        cap_user_header_t hdr = (cap_user_header_t)alloca(sizeof(*hdr));
        cap_user_data_t   cap = (cap_user_data_t)alloca(sizeof(*cap));
        memset(hdr, 0, sizeof(*hdr));
        hdr->version = _LINUX_CAPABILITY_VERSION;
        memset(cap, 0, sizeof(*cap));
        cap->effective = g_uCaps;
        cap->permitted = g_uCaps;
        if (!capset(hdr, cap))
            prctl(PR_SET_KEEPCAPS, 1 /*keep*/, 0, 0, 0);
        prctl(PR_SET_DUMPABLE, 1 /*dump*/, 0, 0, 0);
#  endif /* !USE_LIB_PCAP */
    }

# elif defined(RT_OS_SOLARIS)
    /*
     * Add net_icmpaccess privilege to effective privileges and limit
     * permitted privileges before completely dropping root privileges.
     * This requires dropping root privileges temporarily to get the normal
     * user's privileges.
     */
    seteuid(g_uid);
    priv_set_t *pPrivEffective = priv_allocset();
    priv_set_t *pPrivNew = priv_allocset();
    if (pPrivEffective && pPrivNew)
    {
        int rc = getppriv(PRIV_EFFECTIVE, pPrivEffective);
        seteuid(0);
        if (!rc)
        {
            priv_copyset(pPrivEffective, pPrivNew);
            rc = priv_addset(pPrivNew, PRIV_NET_ICMPACCESS);
            if (!rc)
            {
                /* Order is important, as one can't set a privilege which is
                 * not in the permitted privilege set. */
                rc = setppriv(PRIV_SET, PRIV_EFFECTIVE, pPrivNew);
                if (rc)
                    supR3HardenedError(rc, false, "SUPR3HardenedMain: failed to set effective privilege set.\n");
                rc = setppriv(PRIV_SET, PRIV_PERMITTED, pPrivNew);
                if (rc)
                    supR3HardenedError(rc, false, "SUPR3HardenedMain: failed to set permitted privilege set.\n");
            }
            else
                supR3HardenedError(rc, false, "SUPR3HardenedMain: failed to add NET_ICMPACCESS privilege.\n");
        }
    }
    else
    {
        /* for memory allocation failures just continue */
        seteuid(0);
    }

    if (pPrivEffective)
        priv_freeset(pPrivEffective);
    if (pPrivNew)
        priv_freeset(pPrivNew);
# endif
}
Esempio n. 7
0
/* Specify what privileges an suid root binary needs.  */
int __init_suid_priv (int flags, ...)
{
  int res = 0;
  priv_set_t *permit = NULL, *inherit = NULL, *scratch = NULL;

  /* Check flags.  */
  if (flags != PU_LIMITPRIVS && flags != PU_CLEARLIMITSET)
    return -1;

  /* We can only initialize once.  */
  if (__suidset)
    return -1;

  /* Do nothing if we are running as root but not setuid root.  */
  uid_t uid = getuid ();
  uid_t euid = geteuid ();
  if (uid == 0 && euid == 0)
    return 0;

  /* Allocate a scratch set.  */
  scratch = priv_allocset ();
  if (!scratch)
    goto error;

  /* Get the basic set.  */
  const priv_data_t *pd = __priv_parse_data_cached ();
  if (!pd)
    goto error;
  priv_set_t *basic = pd->pd_basicprivs;

  /* Get the inherited set.  */
  inherit = priv_allocset ();
  if (!inherit)
    goto error;
  if (getppriv (PRIV_INHERITABLE, inherit) != 0)
    goto error;

  /* Get the permitted set.  */
  permit = priv_allocset ();
  if (!permit)
    goto error;
  if (getppriv (PRIV_PERMITTED, permit) != 0)
    goto error;

  /* Get passed privileges.  */
  __suidset = priv_allocset ();
  if (!__suidset)
    goto error;
  priv_emptyset (__suidset);
  va_list ap;
  va_start (ap, flags);
  const char *priv;
  while ((priv = va_arg (ap, const char *)))
    if (priv_addset (__suidset, priv) != 0)
      goto error;

  /* Make sure that the passed privileges are a subset of the current
     permitted privileges.  */
  if (priv_issubset (__suidset, permit) != _B_TRUE)
    goto error;

  /* Set the effective privileges to the inherited ones.  */
  if (setppriv (PRIV_SET, PRIV_EFFECTIVE, inherit) != 0)
    goto error;

  /* Set the permitted privileges to those currently permitted privileges in
     set of the ones passed in, the inherited ones, and the basic set.  */
  priv_copyset (__suidset, scratch);
  priv_union (inherit, scratch);
  if (basic)
    priv_union (basic, scratch);
  priv_intersect (permit, scratch);
  if (setppriv (PRIV_SET, PRIV_PERMITTED, scratch) != 0)
    goto error;

  /* Check if we need to set the limit set.  */
  if (flags & PU_CLEARLIMITSET)
    {
      priv_emptyset (scratch);
      if (setppriv (PRIV_SET, PRIV_LIMIT, scratch) != 0)
        goto error;
    }
  else if (flags & PU_LIMITPRIVS)
    {
      if (setppriv (PRIV_SET, PRIV_LIMIT, scratch) != 0)
        goto error;
    }

  /* Change the uid to the caller's uid if we're setuid root.  */
  if (euid == 0 && setreuid (uid, uid) != 0)
    goto error;

  goto out;

error:
  res = -1;
  if (__suidset)
    {
      priv_freeset (__suidset);
      __suidset = NULL;
    }
  if (euid == 0)
    setreuid (uid, uid);

out:
  priv_freeset (permit);
  priv_freeset (inherit);
  priv_freeset (scratch);

  return res;
}
Esempio n. 8
0
static void
privupdate(prpriv_t *pr, const char *arg)
{
	int i;

	if (sets != NULL) {
		for (i = 0; i < pri->priv_nsets; i++) {
			priv_set_t *target =
			    (priv_set_t *)&pr->pr_sets[pr->pr_setsize * i];
			if (rem[i] != NULL)
				priv_intersect(rem[i], target);
			if (add[i] != NULL)
				priv_union(add[i], target);
			if (assign[i] != NULL)
				priv_copyset(assign[i], target);
		}
	}

	if (Doff || Don || pfexec || xpol) {
		priv_info_uint_t *pii;
		int sz = PRIV_PRPRIV_SIZE(pr);
		char *x = (char *)pr + PRIV_PRPRIV_INFO_OFFSET(pr);
		uint32_t fl = 0;

		while (x < (char *)pr + sz) {
			/* LINTED: alignment */
			priv_info_t *pi = (priv_info_t *)x;

			if (pi->priv_info_type == PRIV_INFO_FLAGS) {
				/* LINTED: alignment */
				pii = (priv_info_uint_t *)x;
				fl = pii->val;
				goto done;
			}
			if (pi->priv_info_size > pr->pr_infosize ||
			    pi->priv_info_size <=  sizeof (priv_info_t) ||
			    (pi->priv_info_size & 3) != 0)
				break;
			x += pi->priv_info_size;
		}
		(void) fprintf(stderr,
		    "%s: cannot find privilege flags to set\n", arg);
		pr->pr_infosize = 0;
		return;
done:

		pr->pr_infosize = sizeof (priv_info_uint_t);
		/* LINTED: alignment */
		pii = (priv_info_uint_t *)
		    ((char *)pr + PRIV_PRPRIV_INFO_OFFSET(pr));

		if (Don)
			fl |= PRIV_DEBUG;
		if (Doff)
			fl &= ~PRIV_DEBUG;
		if (pfexec)
			fl |= PRIV_PFEXEC;
		if (xpol)
			fl |= PRIV_XPOLICY;

		pii->info.priv_info_size = sizeof (*pii);
		pii->info.priv_info_type = PRIV_INFO_FLAGS;
		pii->val = fl;
	} else {
		pr->pr_infosize = 0;
	}
}