Comment 0 for bug 1848567

Revision history for this message
Jamie Strandboge (jdstrand) wrote : autogenerated per-snap snap-update-ns apparmor profile may contain many duplicate rules causing excessive parser memory usage

I decided to profile the memory usage of apparmor_parser for various snap profiles and discovered that some snaps' auto-generated snap-update-ns profile had thousands of duplicate rules (particularly for snaps using the content interface multiple times). This caused a slowdown of the parser to parse the file as well as excessive memory usage. Eg:

$ for i in /var/lib/snapd/apparmor/profiles/snap*gnome-calculator ; do echo "= $i =" ; /usr/bin/time -f "wall: %E, mem: %M Kb" apparmor_parser -QTK $i ; done

= /var/lib/snapd/apparmor/profiles/snap.gnome-calculator.gnome-calculator =
wall: 0:00.43, mem: 22096 Kb

= /var/lib/snapd/apparmor/profiles/snap-update-ns.gnome-calculator =
wall: 0:04.88, mem: 1541680 Kb

Whoa, almost 5 seconds to compile on a modern i7 amd64 system and 1.5G used! What is going on?

$ wc -l /var/lib/snapd/apparmor/profiles/snap-update-ns.gnome-calculator
17547 /var/lib/snapd/apparmor/profiles/snap-update-ns.gnome-calculator

That's a big profile. :)

Using sort -u on the profile, and then putting the preamble (ie "#include <tunables/global>" and "profile ... {") and the trailing "}" in place so that it is a proper profile, I see:

$ wc -l ./snap-update-ns.gnome-calculator.unique
662 ./snap-update-ns.gnome-calculator.unique

$ /usr/bin/time -f "wall: %E, mem: %M Kb" apparmor_parser -QTK ./snap-update-ns.gnome-calculator.unique
wall: 0:00.39, mem: 36276 Kb

That's a *lot* better.

Creating two tasks: there are 2 bugs here: snapd should not be creating a profile with so many duplicate rules and apparmor's deduplication would ideally not use so much memory.

For snapd, I suggest that when auto-generating the snap-update-ns profile, it (efficiently) dedupes before splatting out to the disk. This will cause speedups and lower memory consumption across install and refresh regardless of parser version (not to mention, smaller file sizes).

Attached are the two profiles above generated with snapd 2.42:

$ snap version
snap 2.42
snapd 2.42
series 16
ubuntu 19.04
kernel 5.0.0-29-generic