Commit c29bceb3 authored by John Johansen's avatar John Johansen Committed by James Morris
Browse files

Fix execve behavior apparmor for PR_{GET,SET}_NO_NEW_PRIVS



Add support for AppArmor to explicitly fail requested domain transitions
if NO_NEW_PRIVS is set and the task is not unconfined.

Transitions from unconfined are still allowed because this always results
in a reduction of privileges.

Acked-by: default avatarEric Paris <eparis@redhat.com>
Signed-off-by: default avatarWill Drewry <wad@chromium.org>
Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
Signed-off-by: default avatarAndy Lutomirski <luto@amacapital.net>

v18: new acked-by, new description
Signed-off-by: default avatarJames Morris <james.l.morris@oracle.com>
parent 259e5e6c
Loading
Loading
Loading
Loading
+35 −4
Original line number Diff line number Diff line
@@ -360,10 +360,6 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
	if (bprm->cred_prepared)
		return 0;

	/* XXX: no_new_privs is not usable with AppArmor yet */
	if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
		return -EPERM;

	cxt = bprm->cred->security;
	BUG_ON(!cxt);

@@ -398,6 +394,11 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
			new_profile = find_attach(ns, &ns->base.profiles, name);
		if (!new_profile)
			goto cleanup;
		/*
		 * NOTE: Domain transitions from unconfined are allowed
		 * even when no_new_privs is set because this aways results
		 * in a further reduction of permissions.
		 */
		goto apply;
	}

@@ -459,6 +460,16 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
		/* fail exec */
		error = -EACCES;

	/*
	 * Policy has specified a domain transition, if no_new_privs then
	 * fail the exec.
	 */
	if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
		aa_put_profile(new_profile);
		error = -EPERM;
		goto cleanup;
	}

	if (!new_profile)
		goto audit;

@@ -613,6 +624,14 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
	const char *target = NULL, *info = NULL;
	int error = 0;

	/*
	 * Fail explicitly requested domain transitions if no_new_privs.
	 * There is no exception for unconfined as change_hat is not
	 * available.
	 */
	if (current->no_new_privs)
		return -EPERM;

	/* released below */
	cred = get_current_cred();
	cxt = cred->security;
@@ -754,6 +773,18 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
	cxt = cred->security;
	profile = aa_cred_profile(cred);

	/*
	 * Fail explicitly requested domain transitions if no_new_privs
	 * and not unconfined.
	 * Domain transitions from unconfined are allowed even when
	 * no_new_privs is set because this aways results in a reduction
	 * of permissions.
	 */
	if (current->no_new_privs && !unconfined(profile)) {
		put_cred(cred);
		return -EPERM;
	}

	if (ns_name) {
		/* released below */
		ns = aa_find_namespace(profile->ns, ns_name);