Skip to content

Instantly share code, notes, and snippets.

@dirksan28
Last active August 22, 2026 20:21
Show Gist options
  • Select an option

  • Save dirksan28/f4814eb02a8075b02475f4cd8a918c9b to your computer and use it in GitHub Desktop.

Select an option

Save dirksan28/f4814eb02a8075b02475f4cd8a918c9b to your computer and use it in GitHub Desktop.
Ubuntu - Firefox Apparmor problems in log / switch from SNAP to Mozilla APT-Repo

Complete Firefox Migration Guide: From Snap to Debian APT .deb (Ubuntu)

Restore Firefox’s stability and performance on Ubuntu by switching from the Snap package to Mozilla’s official .deb to overcome configuration caveats and recent Firefox Snap issues.

Motivation:

While using Firefox, numerous
apparmor="DENIED" profile="snap.firefox.firefox" name="/proc/pressure/memory" comm="MemoryPoller"
messages flooded the syslog, making log analysis impossible.

See also

Further investigation revealed these stemmed from missing AppArmor permissions – Firefox's MemoryPoller needed to read system memory pressure, but Snap's rigid confinement blocked it.

Without the ability to poll memory pressure Firefox loses a key signal about system memory state and cannot react properly to low‑memory situations, which can lead to degraded performance or crashes under load.

Unfortunately, corrective settings could not be applied to the SNAP installation because of

  • Profiles in /var/lib/snapd/apparmor/overwritten every snap refresh
  • /etc/apparmor.d/local/snap.firefox.firefoxignored by snapd
  • systemctl restart snapd.apparmoroneshot service, no reload
  • Snap too rigid – no proper override merging

Tip

Solution: Switch to Debian packages from Mozilla Team PPA.

Advantages of .deb Firefox

  • Better RAM usage, native GPU/scrolling
  • Direct file handling, perfect GTK themes, full extensions
  • Customizable AppArmor – local overrides persist across updates
  • Standard apt workflow, no Snap daemon overhead
  • Clean logs – no more DENIED spam in /var/log/syslog´after simple fixes
  • Summary: Firefox shows a much lower CPU footprint and runs noticeably smoother overall.

Step-by-step instructions

This guide summarizes the complete process to migrate Firefox from Snap to the Mozilla Team .deb package on Ubuntu, including APT configuration to prevent Snap reinstallation, and AppArmor profile adjustments to eliminate DENIED log spam while maintaining reasonable security. It preserves all profiles (bookmarks, passwords, extensions) while eliminating Snap's technical limitations.

Caution

Please note that by following the instructions below you are stepping outside the standard Ubuntu approach. As a result, support from the Ubuntu forums will no longer be available, and any assistance may be limited or redirected to other communities. You are doing this at your own risk and should be fully aware of what you are doing - in case of doubt, these changes may put your Ubuntu system at risk.

Hint: If you later decide to return to the official Ubuntu-supported setup, you will find instructions at the end of this gist on how to revert these changes and switch back to Snap.

Note

This guide was successfully tested with FF 146.0 (SNAP) -> firefox/noble,now 146.0+build1-0ubuntu0.24.04.1~mt1 (MOZ/DEBIAN) on Ubuntu 24.04.3 LTS.

1. Complete Snap Removal & .deb Migration

Step 1: Backup (SNAP) Firefox Profile

Caution

SNAP stores the Firefox profiles in a different location. If you don’t back them up, they will be lost during the later procedures. Without a backup, all saved passwords, session information, and browsing history will be permanently deleted.

cp -r ~/snap/firefox/common/.mozilla/firefox ~/.mozilla-firefox-backup

Step 2: Remove Snap & APT Firefox Meta-Package

sudo snap remove --purge firefox
sudo apt purge firefox firefox-locale-*  # Removes APT Snap wrapper

Step 3: Add Mozilla Team PPA & Block Snap

sudo add-apt-repository ppa:mozillateam/ppa -y

Alternatively you could also use the mozilla debian repo instead of the mozillateam-ppa (see https://support.mozilla.org/en-US/kb/install-firefox-linux#w_install-firefox-deb-package-for-debian-based-distributions-recommended ) for details. Be aware that the below mentioned AppArmor rules might be different then.

echo '
Package: snapd
Pin: release a=*
Pin-Priority: -10' | sudo tee /etc/apt/preferences.d/nosnap.pref

Purpose: Prevents apt install firefox from pulling the Snap meta-package. Ubuntu's default firefox APT package is just a Snap wrapper.

Security: None – purely prevents Snap confinement issues.

sudo apt update

Step 4: Install Real .deb Firefox

sudo apt install firefox

Step 5: Restore Firefox-Profile

cp -r ~/.mozilla-firefox-backup/* ~/.mozilla/firefox/
firefox --ProfileManager  # Select & set default profile

Result: Full profile migration (bookmarks, passwords, extensions preserved).

2. AppArmor Local Adjustments:

Note

The Mozilla/Debian .deb installation of Firefox also/still produces AppArmor DENIED errors due to its restrictive default profile blocking legitimate resource access like memory pressure and GPU caching.

You can verify this by running journalctl -f | grep -iE "(apparmor.*firefox|DENIED.*firefox) in a terminal while starting/using Firefox.

These problems will now be finally resolved through targeted local overrides in /etc/apparmor.d/local/usr.bin.firefox. These overrides grant Firefox specific permissions to monitor its processes and subprocesses more effectively, optimize resource usage, and enable hardware acceleration. The adjustments persist across updates, preserve core sandbox security, and provide improved system performance with reduced system load.

Please create/edit:

sudo mkdir -p /etc/apparmor.d/local
sudo nano /etc/apparmor.d/local/usr.bin.firefox

File Content (copy exactly - prevent spaces at EOL):

# memory pressure information (used by sandboxing and performance checks)
/proc/pressure/memory r,

# process cgroup membership (detects container/session environment)
/proc/[0-9]*/cgroup r,

# adjust OOM score for content sandbox processes
/proc/[0-9]*/oom_score_adj w,

# Thread name introspection: Firefox reads /proc/[pid]/task/[tid]/comm for process monitoring
/proc/[0-9]*/task/[0-9]*/comm r,

# GPU shader cache database (read/write/lock); improves graphics performance
owner @{HOME}/.cache/mesa_shader_cache**/mesa_cache.db rwlk,

# Additional Mesa shader cache location used by some drivers
owner @{HOME}/.cache/mesa_shader_cache_db/** rwk,

# read cgroup filesystem to gather system resource info
/sys/fs/cgroup/** r,

# allow loading of DRM/Widevine decryption module used by streaming services
owner @{HOME}/.{firefox,mozilla}/**/libwidevinecdm.so m,

# allow launching helper applications outside Firefox sandbox
/usr/lib/x86_64-linux-gnu/glib-2.0/gio-launch-desktop ix -> unconfined,

# system hardware identification (model/serial; read‑only)
 /sys/devices/virtual/dmi/id/** r,

# allow snap based apps to be started for file associations
/usr/bin/snap ix,

# GTK VFS Metadata (file thumbnails/properties)
dbus (send)
bus=session
interface=org.gtk.vfs.Metadata
path=/org/gtk/vfs/metadata,

# UPower (complete power management - devices + service)
dbus (receive, send)
bus=system
path=/org/freedesktop/UPower**,

# Firefox cache & profiles (full access with locks)
owner @{HOME}/.{firefox,mozilla}/** rwlkix,

# systemd‑logind (complete power/session integration)
dbus (receive, send)
bus=system
path=/org/freedesktop/login1**
interface=org.freedesktop.**,

# Accessibility Bus (screen readers, high contrast)
dbus (send)
bus=session
path=/org/a11y/bus
interface=org.freedesktop.DBus.Properties
member=GetAll,

# systemd-timedated (timezone, date)
dbus (send)
bus=system
path=/org/freedesktop/timedate1
interface=org.freedesktop.DBus.Properties
member=GetAll,

# D-Bus: Standard session bus (broad but safe)
#dbus (send)
#bus=session,

# xdg-desktop-portal (complete desktop integration)
dbus (send)
bus=session
path=/org/freedesktop/portal/**,

# DConf Writer (configuration change + notifications)
dbus (send, receive)
bus=session
path=/ca/desrt/dconf/Writer/**
interface=ca.desrt.dconf.Writer,

# MPRIS MediaPlayer (full bidirectional support)
dbus (receive, send)
bus=session
path=/org/mpris/MediaPlayer2
interface=org.freedesktop.DBus.Properties
member=PropertiesChanged,
dbus (receive, send)
bus=session
path=/org/mpris/MediaPlayer2
interface=org.mpris.MediaPlayer2.Player
member=Seeked,

# MPRIS MediaPlayer (name binding - Firefox as media player)
dbus (bind)
bus=session
name=org.mpris.MediaPlayer2.firefox.*,

# Allow Firefox to receive MPRIS property queries
dbus (receive)
bus=session
path=/org/mpris/MediaPlayer2
interface=org.freedesktop.DBus.Properties
member=GetAll,

# Allow Firefox to release its MPRIS bus name
dbus (send)
bus=session
path=/org/freedesktop/DBus
interface=org.freedesktop.DBus
member=ReleaseName,

# GTK VFS Daemon (file chooser backend, mount tracking)
dbus (send)
bus=session
path=/org/gtk/vfs/**
interface=org.gtk.**,

# Hostname service (system identity queries)
dbus (send)
bus=system
path=/org/freedesktop/hostname1
interface=org.freedesktop.DBus.Properties,

Reload:

sudo apparmor_parser -r /etc/apparmor.d/usr.bin.firefox

Rule Explanations & Security Assessment

click to open
Rule Example Log Message Purpose Security Impact
/proc/pressure/memory r, apparmor="DENIED" ... name="/proc/pressure/memory" ... comm="MemoryPoller" MemoryPoller reads system memory pressure Minimal: Read-only system metric, no user data
/proc/[0-9]*/cgroup r, apparmor="DENIED" ... name="/proc/39014/cgroup" ... comm="57656220436F6E74656E74" Content processes read own cgroup membership Low: Process metadata only, read-only
/proc/[0-9]*/oom_score_adj w, apparmor="DENIED" ... name="/proc/37749/oom_score_adj" ... requested_mask="w" Firefox adjusts OOM priority of own child processes Low: Only affects own processes, no privilege escalation
/proc/[0-9]*/task/[0-9]*/comm r, apparmor="DENIED" ... name="/proc/132553/task/132553/comm" ... comm="53747265616D547E73202335323938" Read thread names of own processes Minimal: Own thread names only
owner @{HOME}/.cache/mesa_shader_cache**/mesa_cache.db rwlk, apparmor="DENIED" ... name="/home/dirk/.cache/mesa_shader_cache_db/part0/mesa_cache.db" ... operation="file_lock" GPU Renderer locks Mesa shader cache files Minimal: User-owned cache, GPU performance only
owner @{HOME}/.cache/mesa_shader_cache_db/** rwk, apparmor="DENIED" ... name="/home/dirk/.cache/mesa_shader_cache_db/part4/mesa_cache.db" ... comm="firefox:disk$0" Disk cache process accesses new Mesa DB format Minimal: User-owned cache, GPU performance only
owner @{HOME}/.{firefox,mozilla}/**/libwidevinecdm.so m, apparmor="DENIED" ... name="/home/dirk/.mozilla/firefox/4zc8eowf.default/gmp-widevinecdm/4.10.2934.0/libwidevinecdm.so" ... comm="MainThread" ... requested_mask="m" Firefox tries to map the library into memory for execution. https://support.mozilla.org/en-US/kb/enable-drm Minimal/Low (narrow scope, standard practice, no privilege escalation): allows memory‑mapping a single library file, but you have to trust Widevine
/sys/fs/cgroup/** r, apparmor="DENIED" ... name="/sys/fs/cgroup/user.slice/user-1000.slice/session-c2.scope/cpu.max" Read cgroup-v2 resource limits (CPU/Memory) Low: Read-only own user.slice limits
dbus (receive, send) bus=system path=/org/freedesktop/UPower**, path="/org/freedesktop/UPower" member="GetAll" Full power service (battery + AC status) None: Hardware power data
/usr/bin/snap ix, name="/usr/bin/snap" comm="firefox" or desktop apps Launch Snap packages (Firefox downloads) Low: Snap confinement handles sandboxing
/usr/lib/x86_64-linux-gnu/glib-2.0/gio-launch-desktop -> unconfined, operation="exec" name="/usr/bin/systemctl" comm="freecad" Desktop apps run unconfined (breaks chain) Acceptable: Normal user apps
dbus (send) bus=session interface=org.gtk.vfs.Metadata ... operation="dbus_method_call" path="/org/gtk/vfs/metadata" interface="org.gtk.vfs.Metadata" member="Set" File thumbnails/properties metadata Minimal: User-owned GTK metadata storage
dbus (receive, send) bus=system path=/org/freedesktop/login1** interface=org.freedesktop.**, path="/org/freedesktop/login1" interface="org.freedesktop.login1.Manager" member="PrepareForSleep"
path="/org/freedesktop/login1" interface="org.freedesktop.DBus.Properties" member="PropertiesChanged"
Enables Firefox to both query and listen for all power and session management signals (e.g. suspend/resume, user logins, lid events). Ensures browser reacts properly to sleep/wake and session transitions. Minimal risk – rule is limited to the login1 namespace; allows only signal and query operations, no privileged writes or control actions.
dbus (send) bus=session interface=org.freedesktop.DBus path=/org/freedesktop/DBus member=ReleaseName, path="/org/freedesktop/DBus" interface="org.freedesktop.DBus" member="ReleaseName" D-Bus name cleanup None: Standard bus protocol
/sys/devices/virtual/dmi/id/** r, name="/sys/devices/virtual/dmi/id/product_name" Hardware detection (telemetry, crash reports) Minimal: Read-only hardware facts (model, serial); standard for browsers
owner /home/**/mozilla/firefox/** mrklix, name="...quicksuggest-other.sql" requested_mask="k" Cache + SQLite locking (QuickSuggest) None: Temporary user cache
owner /home/**/.mozilla/** rwlkix, Profile database operations Firefox settings/profiles Low: User-owned config
dbus (send) bus=session path=/org/freedesktop/portal/desktop interface=org.freedesktop.portal.Registry member=Register, path="/org/freedesktop/portal/desktop" interface="org.freedesktop.portal.Registry" member="Register" File picker, screen sharing Low: Portal-mediated user actions only
dbus (send) bus=system path=/org/freedesktop/login1 interface=org.freedesktop.DBus.Properties member=GetAll, path="/org/freedesktop/login1" interface="org.freedesktop.DBus.Properties" member="GetAll" Full session status (idle, lid) Minimal: Standard session broadcasts
dbus (send) bus=session path=/org/a11y/bus interface=org.freedesktop.DBus.Properties member=GetAll, path="/org/a11y/bus" interface="org.freedesktop.DBus.Properties" member="GetAll" Screen reader/high contrast detection None: Accessibility status only
dbus (send) bus=system path=/org/freedesktop/timedate1 interface=org.freedesktop.DBus.Properties member=GetAll, path="/org/freedesktop/timedate1" interface="org.freedesktop.DBus.Properties" member="GetAll" Timezone/calendar display None: Public system clock data
dbus (send) bus=session path=/org/freedesktop/portal/**, path="/org/freedesktop/portal/desktop" member="Register" ALL portals (file picker, screen share, print) Low: User consent required
dbus (receive, send) bus=session path=/org/mpris/MediaPlayer2 interface=org.mpris.MediaPlayer2.Player member=Seeked, path="/org/mpris/MediaPlayer2" interface="org.mpris.MediaPlayer2.Player" member="Seeked" Media seek/scrub events None: Media position updates
dbus (bind) bus=session name=org.mpris.MediaPlayer2.firefox.*, operation="dbus_bind" name="org.mpris.MediaPlayer2.firefox.instance_1_221" Firefox registers as media player None: Own service name only
dbus (send) bus=session path=/org/gtk/vfs/** interface=org.gtk.**, path="/org/gtk/vfs/mounttracker" interface="org.gtk.vfs.MountTracker" member="LookupMount" Query GVFS for mounts and volume information (file dialogs). Low: Read‑only mount state.
dbus (receive) bus=session path=/org/mpris/MediaPlayer2 interface=org.freedesktop.DBus.Properties member=GetAll, apparmor="DENIED" operation="dbus_method_call" path="/org/mpris/MediaPlayer2" interface="org.freedesktop.DBus.Properties" member="GetAll" Receive MPRIS property queries for media controls Low: Session bus media properties only
dbus (send) bus=session path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=ReleaseName, apparmor="DENIED" operation="dbus_method_call" path="/org/freedesktop/DBus" interface="org.freedesktop.DBus" member="ReleaseName" Release MPRIS bus name when done Minimal: Standard D-Bus name management
dbus (send, receive) bus=session path=/ca/desrt/dconf/Writer/** interface=ca.desrt.dconf.Writer, interface="ca.desrt.dconf.Writer" member="Change" Read/write personal dconf settings, e.g., theme updates or preference saves. Low: User‑scope configuration only.
dbus (send) bus=system path=/org/freedesktop/hostname1 interface=org.freedesktop.DBus.Properties, path="/org/freedesktop/hostname1" member="GetAll" Allow host name and OS information queries. Minimal: Public system info.

3. Security Summary

  • All rules are scoped to Firefox’s own processes, caches, and system‑exposed resource data
  • No access to other users’ data, privileged system files, or expanded network abilities
  • Read/write limited to performance‑related cache files in the user’s home (Firefox/Mozilla profiles, Mesa shader cache)
  • AppArmor main sandbox remains intact (no /etc/, /root/, or cross‑user access)
  • Thread and cgroup introspection allowed only for Firefox‑owned processes (comm, cgroup, OOM score)
  • GTK VFS: Metadata lookups only, no arbitrary file access
  • UPower: Full device/service access (send+receive) but still read‑only and non‑privileged
  • systemd‑logind: Full session/power integration (send+receive) via org.freedesktop.*, still no control operations
  • systemd‑timedated: Read‑only timezone/date properties, no modification ability
  • Accessibility Bus: Read‑only property access for assistive technologies
  • xdg-desktop-portal: Desktop integration only, no privileged operations
  • DConf Writer: Full send+receive for notifications and change events, but no ability to read or modify settings directly
  • MPRIS: Full bidirectional media control (PropertiesChanged, Seeked, GetAll) plus ReleaseName for clean media‑player registration; no privilege escalation
  • MPRIS name binding: Firefox registers as a media player, no additional permissions
  • GTK VFS Daemon: File chooser + mount tracking integration, no privileged operations
  • Hostname service: Read‑only system identity queries, no modification ability
  • gio-launch-desktop: Runs unconfined for file‑opening integration, without weakening Firefox’s confinement
  • snap launcher: Allows starting snap apps for file associations, no additional privileges
  • DMI system info: Read‑only hardware identifiers, no sensitive data exposure
  • Widevine CDM: Module load only, no extra filesystem access beyond Firefox’s own profile

Net Security Impact: Minimal degradation.

Firefox gains fine‑grained control over its own resource management (OOM tuning, cgroup awareness, GPU caching, hardware info, desktop integration, full media controls) while remaining fully confined. Tradeoff: Clean logs + full performance vs. the stricter but noisy default profile.

4. Verification Commands

# Check AppArmor status
sudo aa-status | grep firefox

# Monitor for new DENIED messages
journalctl -f | grep -E "(apparmor.*firefox|DENIED.*firefox|dbus.*firefox)"

# Test Firefox functionality
firefox --ProfileManager  # All profiles intact

5. Maintenance / Troubleshooting

Firefox Xfte start menue integration

If the Xfce starter menu no longer works for Firefox, you need to reset the default applications.

To configure default apps in XFCE, open the Settings Manager and go to Default Applications. There you can set programs for common tasks such as web browsing, mail, file management, and the terminal. For specific file types (MIME types), right‑click a file and choose Open With > Other Application to assign a new default.


Revert back to SNAP

In case you want to switch back to the official Ubuntu SNAP variant of Firefox:

here's a quick undo guide

1. Backup current .deb FF profile

cp -r ~/.mozilla/firefox ~/mozilla-deb-backup

2. Remove .deb Firefox & Mozilla PPA

sudo apt purge firefox
sudo ppa-purge ppa:mozillateam/ppa

3. Remove nosnap.pref (re-enable Snap)

sudo rm /etc/apt/preferences.d/nosnap.pref
sudo apt update

4. Install Snap Firefox

sudo snap install firefox

5. Migrate .deb profile back to Snap location

mkdir -p ~/snap/firefox/common/.mozilla/firefox/
  • Copy the profile either from your existing Debian installation. (compare step1)
    cp -r ~/mozilla-deb-backup/* ~/snap/firefox/common/.mozilla/firefox/
  • Or (if no changes were made to the profile in the meantime) use the profile copy created during the snap-to-deb switch (see above).
    cp -r ~/.mozilla-firefox-backup/* ~/snap/firefox/common/.mozilla/firefox/  # From original Snap backup
firefox --ProfileManager  # Select & set default profile in Snap

6. Remove AppArmor overrides

sudo rm /etc/apparmor.d/local/usr.bin.firefox
sudo apparmor_parser -r /etc/apparmor.d/usr.bin.firefox
@noudio

noudio commented Feb 2, 2026

Copy link
Copy Markdown

Thanks.. It didnt work out-of-the-box, though a lot of directions were indeed very useful! Thanks for that!

Even after setting /etc/apt/preferences.d/nosnap.pref , the normal ubuntu firefox.deb still takes precedence over the mozilla .deb Therefore, it reinstalls the snap.

I created an apt firefox pin to disable the snap (/etc/apt/preferences.d/firefox.pref), and removed the 'nosnap.pref'

/etc/apt/preferences.d/firefox.pref:

Package: firefox
Pin: version 1:*
Pin-priority: -10

After that I again removed the snap snap remove --purge firefox, reinstalled the deb apt install --reinstall firefox,
doing the profile restore again...

You can check the right package selection with 'apt policy'

sudo apt policy firefox
firefox:
  Installed: 147.0.2+build1-0ubuntu0.24.04.1~mt1
  Candidate: 147.0.2+build1-0ubuntu0.24.04.1~mt1
  Version table:
     1:1snap1-0ubuntu5 -10
        500 http://nl.archive.ubuntu.com/ubuntu noble/main amd64 Packages
 *** 147.0.2+build1-0ubuntu0.24.04.1~mt1 500
        500 https://ppa.launchpadcontent.net/mozillateam/ppa/ubuntu noble/main amd64 Packages
        100 /var/lib/dpkg/status

Also the apparmor directions didn't work right out of the box. On my noble installation, there was a symlink /etc/apparmor.d/disable/usr.bin.firefox , that took precedence over the 'local' file. Removing that symlink was necessary.

sudo rm /etc/apparmor.d/disable/usr.bin.firefox

@brendan-pike

Copy link
Copy Markdown

Thanks guys, I noticed that following this I don't seem to have to apply a /etc/apparmor.d/local/usr.bin.firefox and I'm not seeing the errors any more. Perhaps fixed already. In any case I'm happy to switch away from snap, you reckon this same process would work for thunderbird too, I notice its been a massive CPU hog.

@paloliska

Copy link
Copy Markdown

.. just followed this guide. It did not worked until I executed sudo apt remove firefox first. It removes snapd 'placeholder'. After that I was able to install firefox from ppa. Please update the guide.

Thank you

@mivk

mivk commented Apr 1, 2026

Copy link
Copy Markdown

Thank you! It also didn't work for me at first, but after including the steps given in noudio's comment now it works.

@philippe-chartrand

Copy link
Copy Markdown

Excellent instructions, but to late for me. I attempted to proceed removing the snap before finding your instructions. And Firefox was running, so the backup from the snap uninstall failed to backup the data. And I was left with a few years old version of bookmarks, passwords etc. Lucky I has Sync configured with my phone. Oh well, it's like an unexpected spring cleaning.

@philippe-chartrand

Copy link
Copy Markdown

Following the instructions (now on PPA esr) and ran into the same issues that @noudio encountered. I'm on 26.04.

@philippe-chartrand

Copy link
Copy Markdown

Afrer following all instructions, launching firefox 151.0.2
and checking for journalctl -f | grep -E "(apparmor.*firefox|DENIED.*firefox|dbus.*firefox)"

shows issues with operations [ capable, mknod, open, unlink, dbus_method_call ].

But it's way better than before.

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