Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a78c65cb authored by John Johansen's avatar John Johansen Committed by Greg Kroah-Hartman
Browse files

apparmor: fix nnp subset test for unconfined

[ Upstream commit 3ed4aaa94fc07db3cd0c91be95e3e1b9782a2710 ]

The subset test is not taking into account the unconfined exception
which will cause profile transitions in the stacked confinement
case to fail when no_new_privs is applied.

This fixes a regression introduced in the fix for
https://bugs.launchpad.net/bugs/1839037

BugLink: https://bugs.launchpad.net/bugs/1844186


Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent af1f72ad
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -935,7 +935,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
	 * aways results in a further reduction of permissions.
	 */
	if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) &&
	    !unconfined(label) && !aa_label_is_subset(new, ctx->nnp)) {
	    !unconfined(label) &&
	    !aa_label_is_unconfined_subset(new, ctx->nnp)) {
		error = -EPERM;
		info = "no new privs";
		goto audit;
@@ -1213,7 +1214,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
		 * reduce restrictions.
		 */
		if (task_no_new_privs(current) && !unconfined(label) &&
		    !aa_label_is_subset(new, ctx->nnp)) {
		    !aa_label_is_unconfined_subset(new, ctx->nnp)) {
			/* not an apparmor denial per se, so don't log it */
			AA_DEBUG("no_new_privs - change_hat denied");
			error = -EPERM;
@@ -1234,7 +1235,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
		 * reduce restrictions.
		 */
		if (task_no_new_privs(current) && !unconfined(label) &&
		    !aa_label_is_subset(previous, ctx->nnp)) {
		    !aa_label_is_unconfined_subset(previous, ctx->nnp)) {
			/* not an apparmor denial per se, so don't log it */
			AA_DEBUG("no_new_privs - change_hat denied");
			error = -EPERM;
@@ -1429,7 +1430,7 @@ int aa_change_profile(const char *fqname, int flags)
		 * reduce restrictions.
		 */
		if (task_no_new_privs(current) && !unconfined(label) &&
		    !aa_label_is_subset(new, ctx->nnp)) {
		    !aa_label_is_unconfined_subset(new, ctx->nnp)) {
			/* not an apparmor denial per se, so don't log it */
			AA_DEBUG("no_new_privs - change_hat denied");
			error = -EPERM;
+1 −0
Original line number Diff line number Diff line
@@ -281,6 +281,7 @@ bool aa_label_init(struct aa_label *label, int size, gfp_t gfp);
struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp);

bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub);
bool aa_label_is_unconfined_subset(struct aa_label *set, struct aa_label *sub);
struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
					     struct aa_label *set,
					     struct aa_label *sub);
+33 −0
Original line number Diff line number Diff line
@@ -550,6 +550,39 @@ bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub)
	return __aa_label_next_not_in_set(&i, set, sub) == NULL;
}

/**
 * aa_label_is_unconfined_subset - test if @sub is a subset of @set
 * @set: label to test against
 * @sub: label to test if is subset of @set
 *
 * This checks for subset but taking into account unconfined. IF
 * @sub contains an unconfined profile that does not have a matching
 * unconfined in @set then this will not cause the test to fail.
 * Conversely we don't care about an unconfined in @set that is not in
 * @sub
 *
 * Returns: true if @sub is special_subset of @set
 *     else false
 */
bool aa_label_is_unconfined_subset(struct aa_label *set, struct aa_label *sub)
{
	struct label_it i = { };
	struct aa_profile *p;

	AA_BUG(!set);
	AA_BUG(!sub);

	if (sub == set)
		return true;

	do {
		p = __aa_label_next_not_in_set(&i, set, sub);
		if (p && !profile_unconfined(p))
			break;
	} while (p);

	return p == NULL;
}


/**