wg-quick segfaults when running in LXC -- apparmor

Bug #2133632 reported by Pasta
10
This bug affects 1 person
Affects Status Importance Assigned to Milestone
apparmor (Ubuntu)
New
Undecided
Unassigned
net-tools (Ubuntu)
Invalid
Undecided
Unassigned
wireguard (Ubuntu)
Incomplete
Undecided
Unassigned

Bug Description

On Ubuntu 25.10 running inside a Proxmox LXC container, any direct execution
of wg-quick (e.g. "wg-quick up wg0") results in a SIGSEGV. The same command
works perfectly when invoked via "bash /usr/bin/wg-quick up wg0".

Cause:
wg-quick has an AppArmor profile (/etc/apparmor.d/usr.bin.wg-quick). When
wg-quick is execve()'d directly, LXC’s AppArmor+seccomp enforcement switches
to the wg-quick profile which denies some operations (likely ip/nft/sysctl),
causing the process to be killed and reported as a segmentation fault.

Placing the profile in complain mode fixes the issue:
"aa-complain wg-quick"

Disabling the profile also fixes it:
"aa-disable wg-quick"

Running wg-quick via bash bypasses the profile switch, so it works.

Expected:
wg-quick should not segfault in LXC environments. (Note, I did not reproduce the crash in docker, I do not have a non-virtualized ubuntu 25.10 to test in)

Actual:
wg-quick segfaults due to AppArmor enforcement on direct exec only.

Reproduction:
- Proxmox 8.x host
- Ubuntu 25.10 LXC container
- Install wireguard-tools
- Provide wg0.conf
- Run "wg-quick up wg0" → SIGSEGV
- Run "bash /usr/bin/wg-quick up wg0" → works normally

```
root@twentyfive-ten-test:~# lsb_release -rd
Description: Ubuntu 25.10
Release: 25.10
```

```
root@twentyfive-ten-test:~# apt-cache policy apparmor
apparmor:
  Installed: 5.0.0~alpha1-0ubuntu8.1
  Candidate: 5.0.0~alpha1-0ubuntu8.1
  Version table:
 *** 5.0.0~alpha1-0ubuntu8.1 500
        500 http://archive.ubuntu.com/ubuntu questing-updates/main amd64 Packages
        100 /var/lib/dpkg/status
     5.0.0~alpha1-0ubuntu8 500
        500 http://archive.ubuntu.com/ubuntu questing/main amd64 Packages
root@twentyfive-ten-test:~# apt-cache policy wireguard
wireguard:
  Installed: 1.0.20210914-3ubuntu2
  Candidate: 1.0.20210914-3ubuntu2
  Version table:
 *** 1.0.20210914-3ubuntu2 500
        500 http://archive.ubuntu.com/ubuntu questing/universe amd64 Packages
        100 /var/lib/dpkg/status
root@twentyfive-ten-test:~# apt-cache policy wireguard-tools
wireguard-tools:
  Installed: 1.0.20210914-3ubuntu2
  Candidate: 1.0.20210914-3ubuntu2
  Version table:
 *** 1.0.20210914-3ubuntu2 500
        500 http://archive.ubuntu.com/ubuntu questing/main amd64 Packages
        100 /var/lib/dpkg/status
```

Tags: sec-8111
Lukas Märdian (slyon)
tags: added: server-triage-discuss
Revision history for this message
Lukas Märdian (slyon) wrote (last edit ):
Download full text (5.2 KiB)

Thank you for this bug report, I can confirm the segfault in a Questing LXD container:

root@engaging-guinea:~# aa-enforce wg-quick
Setting /usr/bin/wg-quick to enforce mode.
Warning: profile wg-quick represents multiple programs
root@engaging-guinea:~# strace wg-quick
execve("/usr/bin/wg-quick", ["wg-quick"], 0x7ffdc0d05d40 /* 20 vars */) = -1 EACCES (Permission denied)
+++ killed by SIGSEGV +++
Segmentation fault (core dumped)

Passes when in complain mode:
root@engaging-guinea:~# aa-complain wg-quick
Setting /usr/bin/wg-quick to complain mode.
Warning: profile wg-quick represents multiple programs
Warning: profile wg-quick represents multiple programs
root@engaging-guinea:~# wg-quick
Usage: wg-quick [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
  [...]
See wg-quick(8) for more info and examples.

Passes via bash redirection:
root@engaging-guinea:~# bash wg-quick
Usage: wg-quick [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
  [...]
See wg-quick(8) for more info and examples.

I collected the following AppArmor denial logs:

Dez 03 12:23:40 abaconcy kernel: audit: type=1400 audit(1764761020.244:103661): apparmor="DENIED" operation="file_mmap" class="file" namespace="root//lxd-engaging-guinea_<var-snap-lxd-common-lxd>" profile="wg-quick" name="/usr/bin/bash" pid=1402704 comm="wg-quick" requested_mask="r" denied_mask="r" fsuid=1000000 ouid=1000000
Dez 03 12:23:35 abaconcy kernel: audit: type=1400 audit(1764761015.855:103660): apparmor="DENIED" operation="file_mmap" class="file" namespace="root//lxd-engaging-guinea_<var-snap-lxd-common-lxd>" profile="wg-quick" name="/usr/bin/bash" pid=1402695 comm="wg-quick" requested_mask="r" denied_mask="r" fsuid=1000000 ouid=1000000
Dez 03 12:23:32 abaconcy kernel: audit: type=1400 audit(1764761012.289:103659): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" label="lxd-engaging-guinea_</var/snap/lxd/common/lxd>//&:lxd-engaging-guinea_<var-snap-lxd-common-lxd>:unconfined" name="wg-quick//sysctl" pid=1402689 comm="apparmor_parser"
Dez 03 12:23:32 abaconcy kernel: audit: type=1400 audit(1764761012.288:103658): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" label="lxd-engaging-guinea_</var/snap/lxd/common/lxd>//&:lxd-engaging-guinea_<var-snap-lxd-common-lxd>:unconfined" name="wg-quick//nft" pid=1402689 comm="apparmor_parser"
Dez 03 12:23:32 abaconcy kernel: audit: type=1400 audit(1764761012.288:103657): apparmor="STATUS" operation="profile_replace" info="same as current profile, skipping" label="lxd-engaging-guinea_</var/snap/lxd/common/lxd>//&:lxd-engaging-guinea_<var-snap-lxd-common-lxd>:unconfined" name="wg-quick//ip" pid=1402689 comm="apparmor_parser"
Dez 03 12:23:32 abaconcy kernel: audit: type=1400 audit(1764761012.281:103656): apparmor="STATUS" operation="profile_replace" label="lxd-engaging-guinea_</var/snap/lxd/common/lxd>//&:lxd-engaging-guinea_<var-snap-lxd-common-lxd>:unconfined" name="wg-quick" pid=1402689 comm="apparmor_parser"
Dez 03 12:23:26 abaconcy kernel: audit: type=1400 audit(1764761006.927:103655): apparmor="ALLOWED" operation="file_mmap" class="file" namespace="root//lxd-engaging-guinea_<...

Read more...

summary: - wg-quick seg-faults when running in LXC -- apparmour
+ wg-quick segfaults when running in LXC -- apparmor
Changed in wireguard (Ubuntu):
status: New → Triaged
Lukas Märdian (slyon)
Changed in net-tools (Ubuntu):
status: New → Invalid
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

The profile comes from the bin:apparmor package, so there is nothing to be fixed in wireguard itself.

The question that remains is if /usr/bin/bash is a missing rule in that profile, or if there is something fishy going on when wireguard is run inside a lxd container.

@rlee287 have you seen this before? /usr/bin/bash being denied?

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

I'll mark wireguard as incomplete for now, just until we are sure where the problem is, but so far it seems to be in the apparmor package.

Changed in wireguard (Ubuntu):
status: Triaged → Incomplete
tags: removed: server-triage-discuss
Ryan Lee (rlee287)
tags: added: sec-8111
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

In a questing host, wg-quick works fine. A questing lxd on that same host, however, fails as described in this bug. Most intriguing. I suspect the @{exec_path} rule is not working as expected inside lxd:

  # Allow executable mapping and read for the binary
  file mr @{exec_path},

Revision history for this message
John Johansen (jjohansen) wrote :

The @{exec_path} is working fine.

This is a manifestation of the unconfined delegation bug.

Profile attachments for scripts only happens via binfmt_misc. ie. when the script is directly run
  wg-quick ...
instead of via interpreter
  bash /usr/bin/wg-quick ...

the interpreter can be confined, and it can opt to switch to the apparmor profile while running the script. However this just isn't currently done by most interpreters.

The missing mr permission on the interpreter is due to the unconfined delegation bug, causing the mr permissions not to be delegated to wg-quick when run inside of a container.

I will refrain from marking this Bug a duplicate, until after verification against a patched kernel. Hopefully I can get that done today.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.