Skip to content

apparmor: add signal and ptrace rules for stacked profiles#919

Open
bitoku wants to merge 1 commit into
podman-container-tools:mainfrom
bitoku:apparmor-stacking-fix
Open

apparmor: add signal and ptrace rules for stacked profiles#919
bitoku wants to merge 1 commit into
podman-container-tools:mainfrom
bitoku:apparmor-stacking-fix

Conversation

@bitoku

@bitoku bitoku commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

With AppArmor 5.0+, child processes get stacked profiles like profile//&crun. Add //&* wildcard rules for signal and ptrace to match stacked profile peers.

This is a reproducer.
https://gist.github.com/bitoku/6fe0dd11aed0e4dad31eb0171c49279f

This will fix cri-o/cri-o#10036 .

Assisted-by: Claude Code https://claude.com/claude-code

With AppArmor 5.0+ (Ubuntu 25.10+), child processes inside containers
get stacked profiles (e.g. containers-default//&crun). The existing
signal and ptrace peer rules only match the base profile name, causing
DENIED audit events that break systemd-based containers.

Add //&* wildcard rules for signal and ptrace to match any stacked
profile peer.

Signed-off-by: Ayato Tokubi <atokubi@redhat.com>
Assisted-by: Claude Code <https://claude.com/claude-code>
@TomSweeneyRedHat

Copy link
Copy Markdown
Contributor

LGTM

signal (receive) peer=unconfined,
signal (send,receive) peer={{.Name}},
# With AppArmor 5.0+, child processes get a stacked profile.
signal (send,receive) peer={{.Name}}//&*,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you link to official docs for this syntax/change?

Also is this fully backwards compatible? What happens if the rule is loaded on apparmor 4 or earlier will the parser accept that?

@bitoku bitoku Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://gitlab.com/apparmor/apparmor/-/wikis/Release_Notes_5.0.0

I can't find the release note about this change, but apparently AI found the change that caused the issue (sorry about just putting the AI result, but I believe it'll help).

According to the AI , torvalds/linux@a9eb185 this change caused the issue. The AI summary is below.

Details

What changed

Previously, x_to_label() in security/apparmor/domain.c only checked whether the first entry in the exec transition table started with & (the stacking marker).
If the first entry wasn't a stack, stacking was skipped entirely — even if a later entry that actually matched did start with &.

The fix checks the actually matched entry for the & prefix:

  // Before: checked first entry only
  stack = rules->file->trans.table[xindex & AA_X_INDEX_MASK];
  if (*stack != '&') { /* skip stacking */ }
  // After: checks the matched entry
  new = x_table_lookup(profile, xindex, lookupname);
  if (!new || **lookupname != '&')
      break;
  stack = new;

Why this breaks container profiles

With the fix, exec'd processes inside containers now correctly receive a stacked label like cri-containerd.apparmor.d//&unconfined (or crio-default//&crun),
where previously the stacking was silently skipped and they just got cri-containerd.apparmor.d.

Existing signal/ptrace rules like signal (send,receive) peer={{.Name}} only match the bare profile name, not the stacked compound label — hence the DENIED
audit entries.

This has also the detailed explanation, but not mention about the upstream change.
containerd/containerd#12886

I confirmed the config is valid in apparmor 4 environment, but I just ran the reproducer, so not sure if it covers enough scenarios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

common Related to "common" package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

On Ubuntu 26.04, systemd-based container fails to run systemd-journald.service in Kubernetes with CRI-O runtime

3 participants