"snap: not found" error coming from inside running snap

When my python3 snap code is first launched by the user on Ubuntu, it runs this code to connect the home interface:

subprocess.call('snap connect mysnap:user-home-config', shell=True)

…and gets this error:

/bin/sh: 1: snap: not found

It works as I expected it to on Manjaro, launching a password request box and then connecting the interface. But it fails on Ubuntu.

Here is my relevant YAML:

plugs:
    user-home-config:
        interface: home
        read: all

How do people normally manually connect interfaces? And why is snap not found by code running in a snap? That seems like it should be impossible…

because on manjaro snaps run under degraded confinement … in proper confinement no snap has access to the snap command on purpose (ths would be a ginat security hole)…

So how do apps normally manually connect interfaces?

apps don’t …

the purpose of confinement is to give the user control over what an app can access … if apps could self-connect any interfaces randomly that would completely defeat the purpose of confinement …

1 Like

At this point I just need to save data that is created by my app running as the user in such a way that a remove hook running as root in my app can access it.

My app needs access to data that my app created. This doesn’t seem to me like it should be some kind of security breach.

I feel like my app consists of a right hand (user code) and a left hand (root code), while brains that connect the two have to be installed separately.

It’s just very hard for me to believe that this is really the intent behind snapcraft. Apologies if I come across as a little irate. I’ve posted multiple threads over the past 2 months trying to figure out how to accomplish something realistic and workable and simple for the user, and every option I think of turns out to be a dead end.

One thing you can do is to use the home interface with the read: all attribute set. This adds policy which allows the root user to read non-root home directories, and it sounds like exactly what your snap needs to run properly. Try adding this to your snap:

plugs:
    home-read-all:
        interface: home
        read: all

hooks:
    remove:
        plugs: [home-read-all]

If this works, you can request auto-connection of this in the #store category, as the home interface no longer auto-connects when you specify read: all.

1 Like

I set up my YAML just like you said, built the snap, installed it on Ubuntu, and connected the plug manually in the terminal. Then I used the app, automatically creating a file here:

/home/myuser/snap/myapp/common/myfile.txt

Then I ran the remove hook and it still threw this error:

cannot open /home/myuser/snap/myapp/common/myfile.txt: Permission denied

What more do I need to do to give the remove hook access to that user file? Or is there somewhere else I can store data from a user that the remove hook can access?

What is snap connections after you do this?

Interface       Plug                                  Slot             Notes
desktop         myapp:desktop               :desktop         -
desktop-legacy  myapp:desktop-legacy        :desktop-legacy  -
gsettings       myapp:gsettings             :gsettings       -
home            myapp:home-read-all         :home            manual
network         myapp:network               :network         -
network-bind    myapp:network-bind          :network-bind    -
unity7          myapp:unity7                :unity7          -
x11             myapp:x11                   :x11             -

What’s the output of cat /snap/<your-snap-name>/current/meta/snap.yaml ?

name: myapp
version: 0.0.1
summary: myapp does stuff.
description: |
  Yaddah yaddah
apps:
  myapp:
    autostart: myapp.desktop
    command: bin/desktop-launch python3 $SNAP/main.py
    command-chain:
    - snap/command-chain/snapcraft-runner
    plugs:
    - network
    - network-bind
    - desktop
    - desktop-legacy
    - x11
    - unity7
    - home-read-all
    - gsettings
architectures:
- amd64
assumes:
- command-chain
base: core18
confinement: strict
grade: devel
hooks:
  remove:
    plugs:
    - network
    - network-bind
    - home-read-all
plugs:
  home-read-all:
    interface: home
    read: all
  desktop: null
  desktop-legacy: null
  gsettings: null
  network: null
  network-bind: null
  unity7: null
  x11: null
title: myapp

Ah okay, I see what the problem is now. The home interface does not allow reading from $HOME/snap/... at all, with the exception of explicit white-lists of $SNAP_USER_DATA and $SNAP_USER_COMMON for that snap and for the current user the app is running as (so the normal app would be user myuser and the hook would be user root).

What should instead work is to put the files you care about in the home folder directly of the user, like in /home/myuser/my-app-config/file.txt. I have tested this and it works with the home read: all variant of the interface.

@jdstrand what do you think about extending the read: all variant of the home interface to allow also reading/writing by root of the $SNAP_USER_DATA and $SNAP_USER_COMMON directories for normal users? I’m not sure what the AppArmor would look like exactly, but perhaps it is doable.

1 Like

Thank you. That totally solved my problem! I’ll request auto-connection of home-read-all for my snap app.

I also found another solution that does not require the extra interface, which I’ve posted here:

1 Like