Exemplo n.º 1
0
/**
 * aa_setprocattr_changeprofile - handle procattr interface to changeprofile
 * @fqname: args received from writting to /proc/<pid>/attr/current (NOT NULL)
 * @onexec: true if change_profile should be delayed until exec
 * @test: true if this is a test of change_profile permissions
 *
 * Returns: %0 or error code if change_profile fails
 */
int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test)
{
	char *name, *ns_name;

	name = aa_split_fqname(fqname, &ns_name);
	return aa_change_profile(ns_name, name, onexec, test);
}
Exemplo n.º 2
0
/*
 * apparmor_process_label_set: Set AppArmor process profile
 *
 * @label   : the profile to set
 * @default : use the default profile if label is NULL
 * @on_exec : the new profile will take effect on exec(2) not immediately
 *
 * Returns 0 on success, < 0 on failure
 *
 * Notes: This relies on /proc being available.
 */
static int apparmor_process_label_set(const char *label, int use_default,
				      int on_exec)
{
	if (!aa_enabled)
		return 0;

	if (!label) {
		if (use_default)
			label = AA_DEF_PROFILE;
		else
			return 0;
	}

	if (strcmp(label, "unconfined") == 0 && apparmor_am_unconfined()) {
		INFO("apparmor profile unchanged");
		return 0;
	}

	if (on_exec) {
		if (aa_change_onexec(label) < 0) {
			SYSERROR("failed to change exec apparmor profile to %s", label);
			return -1;
		}
	} else {
		if (aa_change_profile(label) < 0) {
			SYSERROR("failed to change apparmor profile to %s", label);
			return -1;
		}
	}

	INFO("changed apparmor%s profile to %s", on_exec ? " exec" : "", label);
	return 0;
}
void aa_change_profile_wrapper (int *ret, char **profile, bool *verbose) {
  if(*verbose){
	  Rprintf("Switching profiles...\n");
  }
  *ret = aa_change_profile (*profile);
  if(*ret != 0){
    *ret = errno;
  }
}
Exemplo n.º 4
0
/*
 * apparmor_process_label_set: Set AppArmor process profile
 *
 * @label   : the profile to set
 * @default : use the default profile if label is NULL
 * @on_exec : this is ignored.  Apparmor profile will be changed immediately
 *
 * Returns 0 on success, < 0 on failure
 *
 * Notes: This relies on /proc being available.
 */
static int apparmor_process_label_set(const char *label, int use_default,
				      int on_exec)
{
	if (!aa_enabled)
		return 0;

	/* user may request that we just ignore apparmor */
	if (label && strcmp(label, AA_UNCHANGED) == 0) {
		INFO("apparmor profile unchanged per user request");
		return 0;
	}

	/*
	 * If we are already confined and no profile was requested,
	 * then default to unchanged
	 */
	if (in_aa_confined_container() && !aa_stacking_supported()) {
		if (label) {
			ERROR("already apparmor confined, but new label requested.");
			return -1;
		}
		return 0;
	}

	if (!label) {
		if (use_default)
			label = AA_DEF_PROFILE;
		else
			return 0;
	}

	if (strcmp(label, "unconfined") == 0 && apparmor_am_unconfined()) {
		INFO("apparmor profile unchanged");
		return 0;
	}

	if (aa_change_profile(label) < 0) {
		SYSERROR("failed to change apparmor profile to %s", label);
		return -1;
	}

	INFO("changed apparmor profile to %s", label);
	return 0;
}
Exemplo n.º 5
0
/*
 * apparmor_process_label_set: Set AppArmor process profile
 *
 * @label   : the profile to set
 * @conf    : the container configuration to use @label is NULL
 * @default : use the default profile if label is NULL
 * @on_exec : this is ignored.  Apparmor profile will be changed immediately
 *
 * Returns 0 on success, < 0 on failure
 *
 * Notes: This relies on /proc being available.
 */
static int apparmor_process_label_set(const char *inlabel, struct lxc_conf *conf,
				      int use_default, int on_exec)
{
	const char *label = inlabel ? inlabel : conf->lsm_aa_profile;

	if (!aa_enabled)
		return 0;

	if (!label) {
		if (use_default)
			label = AA_DEF_PROFILE;
		else
			label = "unconfined";
	}

	if (!check_mount_feature_enabled() && strcmp(label, "unconfined") != 0) {
		WARN("Incomplete AppArmor support in your kernel");
		if (!conf->lsm_aa_allow_incomplete) {
			ERROR("If you really want to start this container, set");
			ERROR("lxc.aa_allow_incomplete = 1");
			ERROR("in your container configuration file");
			return -1;
		}
	}


	if (strcmp(label, "unconfined") == 0 && apparmor_am_unconfined()) {
		INFO("apparmor profile unchanged");
		return 0;
	}

	if (aa_change_profile(label) < 0) {
		SYSERROR("failed to change apparmor profile to %s", label);
		return -1;
	}

	INFO("changed apparmor profile to %s", label);
	return 0;
}
Exemplo n.º 6
0
/**
 * virDomainLxcEnterSecurityLabel:
 * @model: the security model to set
 * @label: the security label to apply
 * @oldlabel: filled with old security label
 * @flags: currently unused, pass 0
 *
 * This API is LXC specific, so it will only work with hypervisor
 * connections to the LXC driver.
 *
 * Attaches the process to the security label specified
 * by @label. @label is interpreted relative to @model
 * Depending on the security driver, this may
 * not take effect until the next call to exec().
 *
 * If @oldlabel is not NULL, it will be filled with info
 * about the current security label. This may let the
 * process be moved back to the previous label if no
 * exec() has yet been performed.
 *
 * Returns 0 on success, -1 on error
 */
int
virDomainLxcEnterSecurityLabel(virSecurityModelPtr model,
                               virSecurityLabelPtr label,
                               virSecurityLabelPtr oldlabel,
                               unsigned int flags)
{
    VIR_DEBUG("model=%p, label=%p, oldlabel=%p, flags=%x",
              model, label, oldlabel, flags);

    virResetLastError();

    virCheckFlagsGoto(0, error);

    virCheckNonNullArgGoto(model, error);
    virCheckNonNullArgGoto(label, error);

    if (oldlabel)
        memset(oldlabel, 0, sizeof(*oldlabel));

    if (STREQ(model->model, "selinux")) {
#ifdef WITH_SELINUX
        if (oldlabel) {
            security_context_t ctx;

            if (getcon(&ctx) < 0) {
                virReportSystemError(errno,
                                     _("unable to get PID %d security context"),
                                     getpid());
                goto error;
            }

            if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("security label exceeds "
                                 "maximum length: %d"),
                               VIR_SECURITY_LABEL_BUFLEN - 1);
                freecon(ctx);
                goto error;
            }

            strcpy(oldlabel->label, (char *) ctx);
            freecon(ctx);

            if ((oldlabel->enforcing = security_getenforce()) < 0) {
                virReportSystemError(errno, "%s",
                                     _("error calling security_getenforce()"));
                goto error;
            }
        }

        if (setexeccon(label->label) < 0) {
            virReportSystemError(errno,
                            _("Cannot set context %s"),
                            label->label);
            goto error;
        }
#else
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("Support for SELinux is not enabled"));
        goto error;
#endif
    } else if (STREQ(model->model, "apparmor")) {
#ifdef WITH_APPARMOR
        if (aa_change_profile(label->label) < 0) {
            virReportSystemError(errno, _("error changing profile to %s"),
                                 label->label);
            goto error;
        }
#else
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                       _("Support for AppArmor is not enabled"));
        goto error;
#endif
    } else if (STREQ(model->model, "none")) {
        /* nothing todo */
    } else {
        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
                       _("Security model %s cannot be entered"),
                       model->model);
        goto error;
    }

    return 0;

 error:
    virDispatchError(NULL);
    return -1;
}
Exemplo n.º 7
0
Arquivo: apparmor.c Projeto: 4b42/lxc
/*
 * apparmor_process_label_set: Set AppArmor process profile
 *
 * @label   : the profile to set
 * @conf    : the container configuration to use @label is NULL
 * @default : use the default profile if label is NULL
 * @on_exec : this is ignored.  Apparmor profile will be changed immediately
 *
 * Returns 0 on success, < 0 on failure
 *
 * Notes: This relies on /proc being available.
 */
static int apparmor_process_label_set(const char *inlabel, struct lxc_conf *conf,
				      int use_default, int on_exec)
{
	const char *label = inlabel ? inlabel : conf->lsm_aa_profile;
	char *curlabel;

	if (!aa_enabled)
		return 0;

	/* user may request that we just ignore apparmor */
	if (label && strcmp(label, AA_UNCHANGED) == 0) {
		INFO("apparmor profile unchanged per user request");
		return 0;
	}

	curlabel = apparmor_process_label_get(getpid());

	if (!aa_stacking_supported() && aa_needs_transition(curlabel)) {
		// we're already confined, and stacking isn't supported

		if (!label || strcmp(curlabel, label) == 0) {
			// no change requested
			free(curlabel);
			return 0;
		}

		ERROR("already apparmor confined, but new label requested.");
		free(curlabel);
		return -1;
	}
	free(curlabel);

	if (!label) {
		if (use_default) {
			if (cgns_supported())
				label = AA_DEF_PROFILE_CGNS;
			else
				label = AA_DEF_PROFILE;
		}
		else
			label = "unconfined";
	}

	if (!check_mount_feature_enabled() && strcmp(label, "unconfined") != 0) {
		WARN("Incomplete AppArmor support in your kernel");
		if (!conf->lsm_aa_allow_incomplete) {
			ERROR("If you really want to start this container, set");
			ERROR("lxc.aa_allow_incomplete = 1");
			ERROR("in your container configuration file");
			return -1;
		}
	}


	if (strcmp(label, "unconfined") == 0 && apparmor_am_unconfined()) {
		INFO("apparmor profile unchanged");
		return 0;
	}

	if (aa_change_profile(label) < 0) {
		SYSERROR("failed to change apparmor profile to %s", label);
		return -1;
	}

	INFO("changed apparmor profile to %s", label);
	return 0;
}
Exemplo n.º 8
0
int fpm_unix_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
{
    int is_root = !geteuid();
    int made_chroot = 0;

    if (wp->config->rlimit_files) {
        struct rlimit r;

        r.rlim_max = r.rlim_cur = (rlim_t) wp->config->rlimit_files;

        if (0 > setrlimit(RLIMIT_NOFILE, &r)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to set rlimit_files for this pool. Please check your system limits or decrease rlimit_files. setrlimit(RLIMIT_NOFILE, %d)", wp->config->name, wp->config->rlimit_files);
        }
    }

    if (wp->config->rlimit_core) {
        struct rlimit r;

        r.rlim_max = r.rlim_cur = wp->config->rlimit_core == -1 ? (rlim_t) RLIM_INFINITY : (rlim_t) wp->config->rlimit_core;

        if (0 > setrlimit(RLIMIT_CORE, &r)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to set rlimit_core for this pool. Please check your system limits or decrease rlimit_core. setrlimit(RLIMIT_CORE, %d)", wp->config->name, wp->config->rlimit_core);
        }
    }

    if (is_root && wp->config->chroot && *wp->config->chroot) {
        if (0 > chroot(wp->config->chroot)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to chroot(%s)",  wp->config->name, wp->config->chroot);
            return -1;
        }
        made_chroot = 1;
    }

    if (wp->config->chdir && *wp->config->chdir) {
        if (0 > chdir(wp->config->chdir)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to chdir(%s)", wp->config->name, wp->config->chdir);
            return -1;
        }
    } else if (made_chroot) {
        if (0 > chdir("/")) {
            zlog(ZLOG_WARNING, "[pool %s] failed to chdir(/)", wp->config->name);
        }
    }

    if (is_root) {

        if (wp->config->process_priority != 64) {
            if (setpriority(PRIO_PROCESS, 0, wp->config->process_priority) < 0) {
                zlog(ZLOG_SYSERROR, "[pool %s] Unable to set priority for this new process", wp->config->name);
                return -1;
            }
        }

        if (wp->set_gid) {
            if (0 > setgid(wp->set_gid)) {
                zlog(ZLOG_SYSERROR, "[pool %s] failed to setgid(%d)", wp->config->name, wp->set_gid);
                return -1;
            }
        }
        if (wp->set_uid) {
            if (0 > initgroups(wp->config->user, wp->set_gid)) {
                zlog(ZLOG_SYSERROR, "[pool %s] failed to initgroups(%s, %d)", wp->config->name, wp->config->user, wp->set_gid);
                return -1;
            }
            if (0 > setuid(wp->set_uid)) {
                zlog(ZLOG_SYSERROR, "[pool %s] failed to setuid(%d)", wp->config->name, wp->set_uid);
                return -1;
            }
        }
    }

#ifdef HAVE_PRCTL
    if (0 > prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)) {
        zlog(ZLOG_SYSERROR, "[pool %s] failed to prctl(PR_SET_DUMPABLE)", wp->config->name);
    }
#endif

    if (0 > fpm_clock_init()) {
        return -1;
    }

#ifdef HAVE_APPARMOR
    if (wp->config->apparmor_hat) {
        char *con, *new_con;

        if (aa_getcon(&con, NULL) == -1) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to query apparmor confinement. Please check if \"/proc/*/attr/current\" is read and writeable.", wp->config->name);
            return -1;
        }

        new_con = malloc(strlen(con) + strlen(wp->config->apparmor_hat) + 3); // // + 0 Byte
        if (!new_con) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to allocate memory for apparmor hat change.", wp->config->name);
            return -1;
        }

        if (0 > sprintf(new_con, "%s//%s", con, wp->config->apparmor_hat)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to construct apparmor confinement.", wp->config->name);
            return -1;
        }

        if (0 > aa_change_profile(new_con)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to change to new confinement (%s). Please check if \"/proc/*/attr/current\" is read and writeable and \"change_profile -> %s//*\" is allowed.", wp->config->name, new_con, con);
            return -1;
        }

        free(con);
        free(new_con);
    }
#endif

    return 0;
}