Skip to content

contrib/apparmor: align whitespace parsing with libapparmor#13278

Open
thaJeztah wants to merge 2 commits into
containerd:mainfrom
thaJeztah:apparmor_fix_whitespace
Open

contrib/apparmor: align whitespace parsing with libapparmor#13278
thaJeztah wants to merge 2 commits into
containerd:mainfrom
thaJeztah:apparmor_fix_whitespace

Conversation

@thaJeztah

@thaJeztah thaJeztah commented Apr 23, 2026

Copy link
Copy Markdown
Member

contrib/apparmor: fix whitespace handling in profile names

The profile we read from /proc/self/attr/current will contain a newline,
resulting in a stray newline to be added to the profile;

Diff:
--- Expected
+++ Actual
@@ -16,3 +16,4 @@
   # Manager may send signals to container processes.
-  signal (receive) peer=unconfined,
+  signal (receive) peer=unconfined
+,
   # Container processes may send signals amongst themselves.

Trim whitespace to account for newlines and fix handling of whitespace as
AppArmor profile names are allowed to contain spaces when quoted; from the
apparmor.d(5) man-page:

PROFILE NAME ( UNQUOTED PROFILE NAME | QUOTED PROFILE NAME )

QUOTED PROFILE NAME = '"' UNQUOTED PROFILE NAME '"'

UNQUOTED PROFILE NAME = (must start with alphanumeric character (after
variable expansion), or '/' AARE have special meanings; see below. May
include VARIABLE. Rules with embedded spaces or tabs must be quoted.)

While we don't use those names in our code, let's make the code correct.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes AppArmor profile generation by ensuring the daemon’s current profile name (read from /proc/self/attr/current) is sanitized to avoid trailing newlines/whitespace that can corrupt the rendered policy template.

Changes:

  • Trim leading/trailing whitespace (including newlines) from the cleaned AppArmor profile name after removing the " (enforce)" suffix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread contrib/apparmor/template.go Outdated
@thaJeztah
thaJeztah force-pushed the apparmor_fix_whitespace branch from c8bb2f8 to a419671 Compare April 23, 2026 19:02
Copilot AI review requested due to automatic review settings April 23, 2026 19:03
@thaJeztah
thaJeztah force-pushed the apparmor_fix_whitespace branch from a419671 to f456e92 Compare April 23, 2026 19:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@thaJeztah
thaJeztah force-pushed the apparmor_fix_whitespace branch from f456e92 to 1c89c8c Compare April 23, 2026 19:05
@thaJeztah thaJeztah added cherry-pick/1.7.x Change to be cherry picked to release/1.7 branch cherry-pick/2.0.x Change to be cherry picked to release/2.0 branch cherry-pick/2.1.x Change to be cherry picked to release/2.1 branch cherry-pick/2.2.x Change to be cherry picked to release/2.2 branch labels Apr 23, 2026
@thaJeztah
thaJeztah marked this pull request as draft April 24, 2026 14:58
Copilot AI review requested due to automatic review settings April 24, 2026 16:02
@thaJeztah
thaJeztah force-pushed the apparmor_fix_whitespace branch from 1c89c8c to a1fc501 Compare April 24, 2026 16:02
@thaJeztah thaJeztah changed the title contrib/apparmor: cleanProfileName: trim whitespace contrib/apparmor: fix whitespace handling in profile names Apr 24, 2026
Comment thread contrib/apparmor/template.go Outdated
// Profile names may contain spaces, so split on " (" rather than the
// first space. Trim whitespace first because the value includes a
// trailing newline.
profile, _, _ = strings.Cut(strings.TrimSpace(profile), " (")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hmm I think it would be safer to go from the end - find the LAST ) and then find a matching ( before it.

Technically the profile name could also include parents.

That's also what the libapparmor does:
https://gitlab.com/apparmor/apparmor/-/blob/master/libraries/libapparmor/src/kernel.c?ref_type=heads#L578-615

With testify, expected values go to the left and use sub-tests.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
Copilot AI review requested due to automatic review settings June 29, 2026 13:24
@thaJeztah
thaJeztah force-pushed the apparmor_fix_whitespace branch from 4ab47b8 to 395340b Compare June 29, 2026 13:24
@kubernetes-prow kubernetes-prow Bot added size/L and removed size/M labels Jun 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread contrib/apparmor/template.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment on lines +144 to +149
if strings.HasSuffix(con, ")") {
// Profile names may contain spaces, so split on the last " (" before
// the trailing ")" rather than the first space.
if i := strings.LastIndex(con[:len(con)-1], " ("); i >= 0 {
return con[:i], con[i+2 : len(con)-1]
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We don't really use the mode, and are only interested in the profile name. For our purpose, such profile names would not us obscure names (profiles including parens). Keeping "valid" values in sync with the kernel won't be a realistic option, so keeping it best effort.

Copilot AI review requested due to automatic review settings June 29, 2026 13:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment thread contrib/apparmor/template.go
Comment thread contrib/apparmor/template_test.go
@thaJeztah
thaJeztah force-pushed the apparmor_fix_whitespace branch from 02dc375 to 7cbc66e Compare June 29, 2026 14:08
@thaJeztah
thaJeztah requested a review from vvoland June 29, 2026 14:10
@thaJeztah thaJeztah changed the title contrib/apparmor: fix whitespace handling in profile names contrib/apparmor: align whitespace parsing with libapparmor Jun 29, 2026
The profile we read from /proc/self/attr/current will contain a newline,
resulting in a stray newline to be added to the profile;

    Diff:
    --- Expected
    +++ Actual
    @@ -16,3 +16,4 @@
       # Manager may send signals to container processes.
    -  signal (receive) peer=unconfined,
    +  signal (receive) peer=unconfined
    +,
       # Container processes may send signals amongst themselves.

Trim whitespace to account for newlines and fix handling of whitespace as
AppArmor profile names are allowed to contain spaces when quoted; from the
[apparmor.d(5)] man-page:

    PROFILE NAME ( UNQUOTED PROFILE NAME | QUOTED PROFILE NAME )

    QUOTED PROFILE NAME = '"' UNQUOTED PROFILE NAME '"'

    UNQUOTED PROFILE NAME = (must start with alphanumeric character (after
    variable expansion), or '/' AARE have special meanings; see below. May
    include VARIABLE. Rules with embedded spaces or tabs must be quoted.)

While we don't use those names in our code, let's make the code correct.

Also update the template to use quotes.

[apparmor.d(5)]: https://manpages.ubuntu.com/manpages/xenial/man5/apparmor.d.5.html

Signed-off-by: Sebastiaan van Stijn <[email protected]>
@thaJeztah
thaJeztah force-pushed the apparmor_fix_whitespace branch from 7cbc66e to 7f2f351 Compare June 29, 2026 15:03
Copilot AI review requested due to automatic review settings June 29, 2026 15:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

}

if strings.HasSuffix(con, ")") {
// Profile names may contain spaces, so split on the last " (" before

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 profile names contain ( or )?

@thaJeztah

thaJeztah commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

Can profile names contain ( or )?

@samuelkarp Sorry, long answer, as I did some extra digging to be sure;


It's not explicitly documented, but there's no real restrictions on the name other than some special characters at the start;

AppArmor profile names are allowed to contain spaces when quoted; see apparmor.d(5)
And the website; https://www.apparmor.net/profiles/profile-types-and-syntax/#profile-names

Profile names

The string that follows profile is a profile name.

Profile names may not begin with the :, ., or + characters. If there are whitespaces, the name must be in quotes.

That's also where the fun start; /proc/<pid>/attr/current does NOT quote the profile name, and has an OPTIONAL (mode).

So technically (I doubt anyone would do this) a name like my profile (complain) is valid;

p='my profile (complain)'; f="$(mktemp)"; printf 'profile "%s" flags=(complain) {\n  file,\n  signal,\n}\n' "$p" > "$f" && sudo apparmor_parser -r "$f" && sudo aa-exec -p "$p" -- sh -c 'printf "self: "; cat /proc/self/attr/current; printf "parent: "; cat /proc/$PPID/attr/current'; sudo apparmor_parser -R "$f"; rm -f "$f"

self: my profile (complain) (complain)
parent: unconfined

Which would be ambiguous if (<mode>) is optional

BUT it looks like the mode is ONLY omitted for unconfined (*mode may be NULL when *label is "unconfined") if I read this manpage correctly; aa_getcon(2))

Some examples of possible returned *label strings are 
"unconfined", "/sbin/dhclient", and "Firefox". The string can
consist of any non-NUL characters but it will be NUL-terminated.
The *label string must be freed using free().

The possible *mode strings are "enforce" and "complain".
Additionally, *mode may be NULL when *label is "unconfined".
The *mode string must not be freed. The *label and *mode strings
come from a single buffer allocation and are separated by a NUL character.

So;

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

Labels

cherry-pick/1.7.x Change to be cherry picked to release/1.7 branch cherry-pick/2.0.x Change to be cherry picked to release/2.0 branch cherry-pick/2.1.x Change to be cherry picked to release/2.1 branch cherry-pick/2.2.x Change to be cherry picked to release/2.2 branch kind/bug size/L

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

5 participants