Acess to /var/... using system-files

Hello,

I would like to access, delete, and create files in the folders:

  • /var/lib/libvirt/qemu/save
  • /var/lib/libvirt/images

The above folders exist on the host.

The system-files plug seemed appropriate so I used it:

plugs:
  libvirt-qemu-save:
    interface: system-files
    write:
      - /var/lib/libvirt/qemu/save
      - /var/lib/libvirt/images
apps:
  appack:
    command: bin/appack
    plugs:
....
      - libvirt-qemu-save

I installed my snap and connected the plug. I even installed in devmode too.

I coded a temporary command to run shell commands from within my snap:

$ appack exec 'ls -la /var/lib/libvirt/images'
Command: ls -la /var/lib/libvirt/images
ls: cannot access '/var/lib/libvirt/images': No such file or directory

I can’t get snappy-debug to output anything when trying to access the folders.

Whatever I do, I can’t seem to access the files. Have I missed something?

Thank you

Not sure what your appack command actually does since you did not share the code of it, but note that you can simply do:

snap run --shell <yoursnap>.<app>

which will spawn a shell directly inside the snap sandbox for such tests (without actually executing <app>)…

Thank you, I didn’t know about this!

My app doesn’t do a whole lot for the moment, all I need to do for the moment is to create a .qcow2 file in /var/lib/libvirt/images.

So far it seems like Snap won’t let me do this at all. Is it possible to begin with?

It should be possible with that interface but indeed it will only work on systems that have that dir already existing, what happens if I would install your snap on any of my machines where this dir does not exist ?

I’m also not sure it will work with two directories in the plug definition, you might need to split this into two separate plugs …

Creating snaps that make assumptions like this about the host system is quite tricky since they will be broken when that condition is not met, can you not store your images in $SNAP_DATA instead ?

It’s fine the application can just error out and print a message if the folder does not exist.

I just tried with only one folder, it yields the same result with my testing.

I looked for clues in this direction, but it seems to me that using another folder than the default one is a huge struggle with libvirt. AppArmor doesn’t let qemu access files outside of /var/lib/libvirt/* so it would mean AppArmor tweaks and at this point it would make everything else meaninggless.

I’m really struggling, currently I cannot think of a better solution, I’m open to any suggestions. Hopefully we can make it work

Well, if it is about qemu running inside your sandbox the following should simply re-map that dir inside your snap so $SNAP_COMMON/libvirt shows up as /var/lib/libvirt to your application …

layout:
  /var/lib/libvirt:
    bind: $SNAP_COMMON/libvirt

(Also note that apparmor rules for packages you stage will not be applied inside your snap)

I am giving this a try, this might work!

I am encountering a silly situation where sudo both does and doesn’t work:

$ appack i /home/paul/APO/APO.zip
Error: Unable to create file /var/lib/libvirt/qemu/save/apo-linux.save: Permission denied (os error 13)
$ sudo appack i /home/paul/APO/APO.zip 
Error: Unable to open file "/home/paul/APO/APO.zip": Permission denied (os error 13)

I suspect that without sudo I can’t write to the layout-bound folder (owned by root), and with sudo the “home” plug allows root’s home dir (/root/whatever), and not mine!

Is there a way to grant both necessary conditions one way or another? (With or without sudo)

Thank you again for your support (and patience!)

can you please share the plugs section of your yml file? I am not sure, but it is like you need the home interface (I am referring to the last 2 lines of the log).

Hi I have the home interface enabled under the plugs section of my main app:

confinement: strict
base: core24

apps:
  appack:
    command: bin/appack
    plugs:
      - libvirt
      - home
      - network
      - alsa
      - pulseaudio
      - x11
      - wayland

try to include gnome extension:

   command: bin/appack
   extensions: [ gnome ]
   plugs:

Try to debug also with snappy-debug (it was helpful for me):

sudo snap install snappy-debug
sudo snappy-debug.security scanlog

check also if connections are enabled:

snap connections jmodules

If you are calling a process that makes read/write operations, be aware that the staging package that you use, could need to access or write in hidden folders. It happened to me to execute a bin file from java application and the binary file tried to write in a hidden directory (.something), it failed, so my java application did not work.

Try also the classic confinement and see what happens (in theory it should work):

confinement: classic

I built the Snap with gnome extension as suggested, but I observe the same results.

Here are the logs I get when running the above commands (with gnome extension), I cannot find anything relevant myself:

$ sudo snappy-debug.security scanlog // Launched "appack i /home/paul/APO/APO.zip"
Placez votre index droit sur le lecteur d’empreintes
INFO: Following '/var/log/syslog'. If have dropped messages, use:
INFO: $ sudo journalctl --output=short --follow --all | sudo snappy-debug
kernel.printk_ratelimit = 0
= AppArmor =
Time: Oct 19 06:46:01
Log: apparmor="DENIED" operation="file_inherit" class="file" profile="snap-update-ns.appack" name="/dev/pts/0" pid=14707 comm="snap-update-ns" requested_mask="wr" denied_mask="wr" fsuid=1000 ouid=1000
File: /dev/pts/0 (write)

= AppArmor =
Time: Oct 19 06:46:01
Log: apparmor="DENIED" operation="open" class="file" profile="snap-update-ns.appack" name="/apparmor/.null" pid=14707 comm="snap-update-ns" requested_mask="wr" denied_mask="wr" fsuid=1000 ouid=0
File: /apparmor/.null (write)
Suggestion:
* adjust program to write to $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Oct 19 06:46:01
Log: apparmor="DENIED" operation="file_inherit" class="file" profile="snap-update-ns.appack" name="/dev/pts/0" pid=14707 comm="snap-update-ns" requested_mask="wr" denied_mask="wr" fsuid=1000 ouid=1000
File: /dev/pts/0 (write)

= AppArmor =
Time: Oct 19 06:46:02
Log: apparmor="DENIED" operation="ptrace" class="ptrace" profile="libvirtd" pid=1332 comm="rpc-libvirtd" requested_mask="read" denied_mask="read" peer="snap.appack.appack"
Ptrace: peer=snap.appack.appack (read)
Suggestions:
* add 'system-observe' to 'plugs'
* do nothing if program otherwise works properly

^C
kernel.printk_ratelimit = 5

$ sudo snappy-debug.security scanlog // Launched "sudo appack i /home/paul/APO/APO.zip"
INFO: Following '/var/log/syslog'. If have dropped messages, use:
INFO: $ sudo journalctl --output=short --follow --all | sudo snappy-debug
kernel.printk_ratelimit = 0
= AppArmor =
Time: Oct 19 06:46:12
Log: apparmor="DENIED" operation="capable" class="cap" profile="snap.appack.appack" pid=14824 comm="desktop-launch" capability=2  capname="dac_read_search"
Capability: dac_read_search
Suggestions:
* adjust program to not require 'CAP_DAC_READ_SEARCH' (see 'man 7 capabilities')
* add one of 'microstack-support, system-backup' to 'plugs'
* do nothing if program otherwise works properly

= AppArmor =
Time: Oct 19 06:46:12
Log: apparmor="DENIED" operation="capable" class="cap" profile="snap.appack.appack" pid=14824 comm="desktop-launch" capability=1  capname="dac_override"
Capability: dac_override
Suggestions:
* adjust program to not require 'CAP_DAC_OVERRIDE' (see 'man 7 capabilities')
* add one of 'log-observe, microstack-support' to 'plugs'
* do nothing if program otherwise works properly

= AppArmor =
Time: Oct 19 06:46:12
Log: apparmor="DENIED" operation="mkdir" class="file" profile="snap.appack.appack" name="/run/user/0/" pid=14877 comm="mkdir" requested_mask="c" denied_mask="c" fsuid=0 ouid=0
File: /run/user/0/ (write)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use /run/shm/snap.$SNAP_NAME.*
* adjust program to use /run/snap.$SNAP_NAME.*
* adjust snap to use snap layouts (https://forum.snapcraft.io/t/snap-layouts/7207)

= AppArmor =
Time: Oct 19 06:46:12
Log: apparmor="DENIED" operation="capable" class="cap" profile="snap.appack.appack" pid=14824 comm="appack" capability=2  capname="dac_read_search"
Capability: dac_read_search
Suggestions:
* adjust program to not require 'CAP_DAC_READ_SEARCH' (see 'man 7 capabilities')
* add one of 'microstack-support, system-backup' to 'plugs'
* do nothing if program otherwise works properly

= AppArmor =
Time: Oct 19 06:46:12
Log: apparmor="DENIED" operation="capable" class="cap" profile="snap.appack.appack" pid=14824 comm="appack" capability=1  capname="dac_override"
Capability: dac_override
Suggestions:
* adjust program to not require 'CAP_DAC_OVERRIDE' (see 'man 7 capabilities')
* add one of 'log-observe, microstack-support' to 'plugs'
* do nothing if program otherwise works properly

^C
kernel.printk_ratelimit = 5

I know accessing hidden files is not possible using Snap. Fortunately none of the files I want to manipulate should be hidden.

It should probably work with classic confinement, however the app I’m trying to create is clearly mentioned as “unsupported” for passing classic confinement review so this isn’t an option.

To focus on the current bottleneck, we can consider the following pseudo code:

fn main() {
  1. cat /home/paul/test.txt
  2. cat /var/lib/libvirt/qemu/save/test.txt
}

With sudo:

  • instruction 1 fails (/home/paul is not root’s home dir)
  • instruction 2 succeeds

Without sudo:

  • instruction 1 succeeds
  • instruction 2 fails

Is there anything obvious that I missed? Is it just not possible to do what I’m trying to achieve with the current design of Snap ?

Thank you

I finally managed to solve this home plug issue using the read: all attribute.

After re-reading carefully what you said, I understand that I will have to run Qemu from within the Snap. Is that right?

I will explore this possibility, probably following your work on qemu-virgil!

1 Like

For closure, I will rethink the architecture of my app to run Qemu inside the snap, instead of using the host’s files and programs, as ogra suggested.

Thank you to all participants for leading me in the right direction :slight_smile:

1 Like