Hi everyone,
I am trying to create a new snap for the calibre application. I have correctly created the snapcraft.yaml file and works fine for me in classic mode when using it in my development environment.
The problem comes when we try to restrict it to strict confinement. The calibre package internally tries to create a unix socket, and this is forbidden in my snap environemnt.
Here is the Python traceback (strict confinement):
Traceback (most recent call last):
File "runpy.py", line 194, in _run_module_as_main
File "runpy.py", line 87, in _run_code
File "site.py", line 45, in <module>
File "site.py", line 41, in main
File "calibre/gui_launch.py", line 73, in calibre
File "calibre/gui2/main.py", line 501, in main
File "calibre/utils/lock.py", line 195, in __enter__
File "calibre/utils/lock.py", line 149, in create_single_instance_mutex
File "calibre/utils/ipc/__init__.py", line 23, in eintr_retry_call
PermissionError: [Errno 13] Permission denied
Here is the method of calibre where the socket is created.
Here are the permissions for the app command:
apps:
calibre:
command: calibre/calibre
plugs:
- desktop
- home
- x11
- network
- network-bind
- network-control
- process-control
Thank you for all.
ogra
October 31, 2020, 2:59pm
2
more interesting than the traceback would be to get the output of dmesg | grep DENIED (or a journal excerpt for calibre) to see any apparmor denials.
Here is the dmesg output:
[19605.284167] audit: type=1400 audit(1604157007.517:13828): apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/snap/core18/1932/lib/x86_64-linux-gnu/librt-2.27.so" pid=64203 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
[19605.284178] audit: type=1400 audit(1604157007.517:13829): apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/snap/core18/1932/lib/x86_64-linux-gnu/librt-2.27.so" pid=64203 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
[19605.284220] audit: type=1400 audit(1604157007.517:13830): apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/snap/core18/1932/lib/x86_64-linux-gnu/librt-2.27.so" pid=64203 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
[19605.284227] audit: type=1400 audit(1604157007.517:13831): apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/snap/core18/1932/lib/x86_64-linux-gnu/librt-2.27.so" pid=64203 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
[19605.284235] audit: type=1400 audit(1604157007.517:13832): apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/snap/core18/1932/lib/x86_64-linux-gnu/librt-2.27.so" pid=64203 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
[19605.284241] audit: type=1400 audit(1604157007.517:13833): apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/snap/core18/1932/lib/x86_64-linux-gnu/librt-2.27.so" pid=64203 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
[19605.347972] audit: type=1400 audit(1604157007.581:13834): apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/snap/core18/1932/lib/x86_64-linux-gnu/libuuid.so.1.3.0" pid=64203 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
[19605.360939] audit: type=1400 audit(1604157007.593:13835): apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/sys/devices/pci0000:00/0000:00:02.0/vendor" pid=64203 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
[19605.360967] audit: type=1400 audit(1604157007.593:13836): apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/sys/devices/pci0000:00/0000:00:02.0/vendor" pid=64203 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
[19605.361108] audit: type=1400 audit(1604157007.593:13837): apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/sys/devices/pci0000:00/0000:00:02.0/vendor" pid=64203 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
Here is also the snappy-debug output
david@hp:~/devel/snap/calibre$ snappy-debug.security scanlog
INFO: Following '/var/log/syslog'. If have dropped messages, use:
INFO: $ sudo journalctl --output=short --follow --all | sudo snappy-debug
= AppArmor =
Time: Oct 31 16:26:14
Log: apparmor="DENIED" operation="open" profile="snap.calibre-unofficial.calibre" name="/sys/devices/pci0000:00/0000:00:02.0/vendor"
pid=69607 comm="calibre" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /sys/devices/pci0000:00/0000:00:02.0/vendor (read)
Suggestions:
* adjust program to not access '/sys/devices/pci0000:00/0000:00:02.0/vendor'
* adjust program to not access '/sys/devices/pci[0-9]*:[0-9]*/[0-9]*:[0-9]*:[0-9]*.[0-9]*/vendor'
= AppArmor =
Time: Oct 31 16:26:14
Log: apparmor="DENIED" operation="bind" profile="snap.calibre-unofficial.calibre" pid=69607 comm="calibre" family="unix" sock_type="s
tream" protocol=0 requested_mask="bind" denied_mask="bind" addr="@calibre-singleinstance-1000-GUI"
Suggestions:
* adjust '@calibre-singleinstance-1000-GUI' to start with 'snap.calibre-unofficial.' (eg, '@snap.calibre-unofficial.calibre-singleins
tance-1000-GUI')
* use 'listen-stream: @snap.calibre-unofficial.calibre-singleinstance-1000-GUI' for a socket-activated daemon
2 Likes
davidalo6:
adjust ‘@calibre-singleinstance-1000-GUI ’ to start with ‘snap.calibre-unofficial.’ (eg, ‘@snap.calibre-unofficial.calibre-singleins tance-1000-GUI’)
This seems to be the proper way to deal with this problem, however the source code needs to be patched means that the prebuilt distribution can’t be used.
ogra
November 1, 2020, 1:46am
7
calibre is python, if lock.py is the only place where the socket name is defined, then a simple sed command in an override-pull scriptlet should be enough …
mutex = winutil.create_mutex(mutexname, False) except FileExistsError: return return mutex.close elif islinux: def create_single_instance_mutex(name, per_user=True): import socket from calibre.utils.ipc import eintr_retry_call name = '%s-singleinstance-%s-%s' % ( __appname__, (os.geteuid() if per_user else ''), name ) name = name address = '\0' + name.replace(' ', '_') sock = socket.socket(family=socket.AF_UNIX) try: eintr_retry_call(sock.bind, address) except socket.error as err: if getattr(err, 'errno', None) == errno.EADDRINUSE: return
i.e. something like:
override-pull: |
snapcraftctl pull
sed "s/\%s-singleinstance/snap.$SNAPCRAFT_PROJECT_NAME-%s-singleinstance/" path/to/lock.py
should work …
(path/to/lock.py is relative to parts/<yourpart>/src)
1 Like
I have taken a look and the official download script seems to download a binary executable, not source code. So I may have to build it or try to use in source.
In the git home page there are instructions for linux installation, I will try it this weekend