Strict confinement - read all paths

What plug must I use if I have an application that needs to be able to read any file on any disk?

Working in my home path:
→ grex --file inpt.txt
^(?:input.txt|2002)$

But everywhere else:
→ sudo grex --file /etc/vim/vimrc
permission denied: the specified file could not be opened

What plug must I use to allow read. I tried “/” but that triggers a manual review.

When there is a file I want to read on disc I get read errors. Data is an extra drive I mounted to my host.
fstab:
/dev/mapper/vgmint-root / ext4
/dev/mapper/sda /Data ext4

→ pwd
/Data/Tools

→ ll test_port80.pl
-rwxr-x— 1 user1 adm 467 Mar 19 2020 test_port80.pl

→ grex --file test_port80.pl
error: the specified file could not be found

I created my snapcraft.yml like this:

apps:
  grex:
    command: bin/grex
    plugs:
      - home
      - removable-media

When I run snappy-debug the error event is not logged.

Please see the documentation of removable-media interface to understand why /Data does not work.

Also because of confinement, you will not be able to access all of the files on the host. Perhaps your snap has a legitimate reason to be a classic one? Can you describe what it does?

@mborzecki It is not apparent why /Data won’t work after reading the documentation again.

The utility either reads stdin or a file to create regular expressions. I’m mostly ok with the limitation that the app won’t be able to read files outside of $HOME but I have other snaps that have similar shortcomings where something like ncdu would need to read a volume to calculate its usage. I’m not sure how to deal with the need to read a file for input or a path outside $HOME.

Removable media only allows access to paths under /media and /mnt. The /Data location is not known to snapd and not covered by any interface.

When a snap runs, a sandbox is created for it, where / is the base snap. Some paths are bind mounted to become available inside, and on top of this AppArmor is used to selectively allow access to those locations.

In your case /Data is not available inside the snap’s sandbox (thus accessing /Data/foo will yield ENOENT error). The /home directory is bind mounted inside the sandbox, and using the home interface allows accessing files inside it. The /etc/ directory from the host is visible inside the sandbox, but only few interfaces allow accessing paths from there, and if so those are limited to files that are relevant for a particular interface.

Thanks for clarifying, that’s what I was thinking. I added Home and removable-media as 2 possible locations where files could be read from. A volume could be mounted anywhere. How can I read from anywhere? To do that do I need a classic confinement or is there something else I can look at? Especially if you only need to read.

There’s a system files interface, but you need to know the locations upfront, and since it requires a snap declaration, you must request it in the forum (also static which paths you want). I understand it’s not practical for your scenario.

I’ve briefly looked at the project page https://github.com/pemistahl/grex and if --file is the only feature you really need this for, then perhaps home and removable-media is enough, and for other locations the input can be passed in stdin, eg.

cat /my/random/location | grex --file - 

AFAIK this is how the shellcheck snap works.

1 Like

@mborzecki I did not get grex to work exactly as proposed but xargs was successful. That counts as a win!

cat /Data/AD.groups | xargs grex

What I don’t understand is that I can’t directly run the application from /Data as I’ll get an error but if I browse to /var/lib/snapd/hostfs I can access all the paths without error.
image
Is the software I package supposed to use that path rather?

That’s because /Data on the outside, is not the same location inside the mount namespace of the process running from a snap. When the snap starts up, snap-confine creates a new rootfs for it using the base snap, for example inside the snap mount namespace what you see under /snap/core20/current is the content of /. Next, select locations from the host are mounted inside the mount namespace, eg. /home -> /home, /media -> /media, /mnt -> /mnt. All of the host hierarchy is visible under /var/lib/snapd/hostfs, and parts of it are still accessible with the right interfaces.

Thus when you run grex /Data/foo, when the grex process runs and reads the command line arguments, /Data/foo no longer exists in its mount namespace.

@mborzecki I’m sorry. Is there another way for you to explain? I’ve been using various applications to understand how snap allows access to drives. Grex and ncdu are two apps I’m working on to understand snap packages better.

What I don’t understand is that an app like ncdu, the previous screenshot is from that app, can access the path if I use /var/lib/snapd/hostfs but not if I run it from /Data. ncdu has a TUI so it does not terminal after running like grex.