Bash or lxc stdout weirdness: Error: write /dev/stdout: permission denied

Here is something I don’t quite understand yet. I can get the JSON list but not redirect it (var is a symlink):

$ lxc list -f json h1:
<snip long JSON is OK>
$ lxc list h1: > var/targets/hypervisor/h1/lxd.json #not a JSON but works
$ lxc list -f json h1: > var/targets/hypervisor/h1/lxd.json
Error: write /dev/stdout: permission denied
$ lxc list -f json h1: | jq . > var/targets/hypervisor/h1/lxd.json

Any clues what is going on here? Is LXC JSON output coming as a different user?

Hmm, no, there’s no logic for any kind of privilege dropping or anything in the lxc command.

It could be some weird apparmor behavior but since you’re always writing to the same path, it’s a bit weird.

Yes, it seems it is:

[15226849.140078] audit: type=1400 audit(1671799401.454:124152): apparmor="DENIED" operation="file_inherit" namespace="root//lxd-control_<var-snap-lxd-common-lxd>" profile="/snap/snapd/17883/usr/lib/snapd/snap-confine" name="/srv/tools/var/targets/hypervisor/h1/lxd.json" pid=1477962 comm="snap-confine" requested_mask="w" denied_mask="w" fsuid=1001000 ouid=1001000
[15226849.150616] audit: type=1400 audit(1671799401.466:124153): apparmor="DENIED" operation="file_inherit" namespace="root//lxd-control_<var-snap-lxd-common-lxd>" profile="snap.lxd.lxc" name="/apparmor/.null" pid=1477962 comm="snap-exec" requested_mask="wr" denied_mask="wr" fsuid=1001000 ouid=0
[15226849.174224] audit: type=1400 audit(1671799401.486:124154): apparmor="DENIED" operation="file_inherit" namespace="root//lxd-control_<var-snap-lxd-common-lxd>" profile="/snap/snapd/17883/usr/lib/snapd/snap-confine" name="/apparmor/.null" pid=1477962 comm="aa-exec" requested_mask="wr" denied_mask="wr" fsuid=1001000 ouid=0

This is on a control node lxd container where lxc accesses remote lxd’s and is installed from snap. Something in this seems to trigger apparmor in unpredictable ways.

You may want to report that at https://forum.snapcraft.io as those denial entries show the profile as being that of snap-confine itself and not one of the LXD profiles.

So it’s basically policy applied to the snap commands themselves that’s getting in the way here.