Commit 8b45c6c9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'apparmor-pr-2025-08-04' of...

Merge tag 'apparmor-pr-2025-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor

Pull apparmor updates from John Johansen:
 "This has one major feature, it pulls in a cleaned up version of
  af_unix mediation that Ubuntu has been carrying for years. It is
  placed behind a new abi to ensure that it does cause policy
  regressions. With pulling in the af_unix mediation there have been
  cleanups and some refactoring of network socket mediation. This
  accounts for the majority of the changes in the diff.

  In addition there are a few improvements providing minor code
  optimizations. several code cleanups, and bug fixes.

  Features:
   - improve debug printing
   - carry mediation check on label (optimization)
   - improve ability for compiler to optimize
     __begin_current_label_crit_section
   - transition for a linked list of rulesets to a vector of rulesets
   - don't hardcode profile signal, allow it to be set by policy
   - ability to mediate caps via the state machine instead of lut
   - Add Ubuntu af_unix mediation, put it behind new v9 abi

  Cleanups:
   - fix typos and spelling errors
   - cleanup kernel doc and code inconsistencies
   - remove redundant checks/code
   - remove unused variables
   - Use str_yes_no() helper function
   - mark tables static where appropriate
   - make all generated string array headers const char *const
   - refactor to doc semantics of file_perm checks
   - replace macro calls to network/socket fns with explicit calls
   - refactor/cleanup socket mediation code preparing for finer grained
     mediation of different network families
   - several updates to kernel doc comments

  Bug fixes:
   - fix incorrect profile->signal range check
   - idmap mount fixes
   - policy unpack unaligned access fixes
   - kfree_sensitive() where appropriate
   - fix oops when freeing policy
   - fix conflicting attachment resolution
   - fix exec table look-ups when stacking isn't first
   - fix exec auditing
   - mitigate userspace generating overly large xtables"

* tag 'apparmor-pr-2025-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor: (60 commits)
  apparmor: fix: oops when trying to free null ruleset
  apparmor: fix Regression on linux-next (next-20250721)
  apparmor: fix test error: WARNING in apparmor_unix_stream_connect
  apparmor: Remove the unused variable rules
  apparmor: fix: accept2 being specifie even when permission table is presnt
  apparmor: transition from a list of rules to a vector of rules
  apparmor: fix documentation mismatches in val_mask_to_str and socket functions
  apparmor: remove redundant perms.allow MAY_EXEC bitflag set
  apparmor: fix kernel doc warnings for kernel test robot
  apparmor: Fix unaligned memory accesses in KUnit test
  apparmor: Fix 8-byte alignment for initial dfa blob streams
  apparmor: shift uid when mediating af_unix in userns
  apparmor: shift ouid when mediating hard links in userns
  apparmor: make sure unix socket labeling is correctly updated.
  apparmor: fix regression in fs based unix sockets when using old abi
  apparmor: fix AA_DEBUG_LABEL()
  apparmor: fix af_unix auditing to include all address information
  apparmor: Remove use of the double lock
  apparmor: update kernel doc comments for xxx_label_crit_section
  apparmor: make __begin_current_label_crit_section() indicate whether put is needed
  ...
parents d2eedaa3 5f49c2d1
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
apparmor-y := apparmorfs.o audit.o capability.o task.o ipc.o lib.o match.o \
              path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
              resource.o secid.o file.o policy_ns.o label.o mount.o net.o \
              policy_compat.o
              policy_compat.o af_unix.o
apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o

obj-$(CONFIG_SECURITY_APPARMOR_KUNIT_TEST) += apparmor_policy_unpack_test.o
@@ -28,7 +28,7 @@ clean-files := capability_names.h rlim_names.h net_names.h
# to
#    #define AA_SFS_AF_MASK "local inet"
quiet_cmd_make-af = GEN     $@
cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
cmd_make-af = echo "static const char *const address_family_names[] = {" > $@ ;\
	sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \
	 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
	echo "};" >> $@ ;\
@@ -43,7 +43,7 @@ cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
# to
#    [1] = "stream",
quiet_cmd_make-sock = GEN     $@
cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
cmd_make-sock = echo "static const char *const sock_type_names[] = {" >> $@ ;\
	sed $^ >>$@ -r -n \
	-e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
	echo "};" >> $@
+799 −0

File added.

Preview size limit exceeded, changes collapsed.

+28 −11

File changed.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ int aa_audit(int type, struct aa_profile *profile,
	aa_audit_msg(type, ad, cb);

	if (ad->type == AUDIT_APPARMOR_KILL)
		(void)send_sig_info(SIGKILL, NULL,
		(void)send_sig_info(profile->signal, NULL,
			ad->common.type == LSM_AUDIT_DATA_TASK &&
			ad->common.u.tsk ? ad->common.u.tsk : current);

+57 −4
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

struct aa_sfs_entry aa_sfs_entry_caps[] = {
	AA_SFS_FILE_STRING("mask", AA_SFS_CAPS_MASK),
	AA_SFS_FILE_BOOLEAN("extended", 1),
	{ }
};

@@ -68,8 +69,7 @@ static int audit_caps(struct apparmor_audit_data *ad, struct aa_profile *profile
{
	const u64 AUDIT_CACHE_TIMEOUT_NS = 1000*1000*1000; /* 1 second */

	struct aa_ruleset *rules = list_first_entry(&profile->rules,
						    typeof(*rules), list);
	struct aa_ruleset *rules = profile->label.rules[0];
	struct audit_cache *ent;
	int type = AUDIT_APPARMOR_AUTO;

@@ -121,10 +121,32 @@ static int audit_caps(struct apparmor_audit_data *ad, struct aa_profile *profile
static int profile_capable(struct aa_profile *profile, int cap,
			   unsigned int opts, struct apparmor_audit_data *ad)
{
	struct aa_ruleset *rules = list_first_entry(&profile->rules,
						    typeof(*rules), list);
	struct aa_ruleset *rules = profile->label.rules[0];
	aa_state_t state;
	int error;

	state = RULE_MEDIATES(rules, ad->class);
	if (state) {
		struct aa_perms perms = { };
		u32 request;

		/* caps broken into 256 x 32 bit permission chunks */
		state = aa_dfa_next(rules->policy->dfa, state, cap >> 5);
		request = 1 << (cap & 0x1f);
		perms = *aa_lookup_perms(rules->policy, state);
		aa_apply_modes_to_perms(profile, &perms);

		if (opts & CAP_OPT_NOAUDIT) {
			if (perms.complain & request)
				ad->info = "optional: no audit";
			else
				ad = NULL;
		}
		return aa_check_perms(profile, &perms, request, ad,
				      audit_cb);
	}

	/* fallback to old caps mediation that doesn't support conditionals */
	if (cap_raised(rules->caps.allow, cap) &&
	    !cap_raised(rules->caps.denied, cap))
		error = 0;
@@ -168,3 +190,34 @@ int aa_capable(const struct cred *subj_cred, struct aa_label *label,

	return error;
}

kernel_cap_t aa_profile_capget(struct aa_profile *profile)
{
	struct aa_ruleset *rules = profile->label.rules[0];
	aa_state_t state;

	state = RULE_MEDIATES(rules, AA_CLASS_CAP);
	if (state) {
		kernel_cap_t caps = CAP_EMPTY_SET;
		int i;

		/* caps broken into up to 256, 32 bit permission chunks */
		for (i = 0; i < (CAP_LAST_CAP >> 5); i++) {
			struct aa_perms perms = { };
			aa_state_t tmp;

			tmp = aa_dfa_next(rules->policy->dfa, state, i);
			perms = *aa_lookup_perms(rules->policy, tmp);
			aa_apply_modes_to_perms(profile, &perms);
			caps.val |= ((u64)(perms.allow)) << (i * 5);
			caps.val |= ((u64)(perms.complain)) << (i * 5);
		}
		return caps;
	}

	/* fallback to old caps */
	if (COMPLAIN_MODE(profile))
		return CAP_FULL_SET;

	return rules->caps.allow;
}
Loading