Snapd Interfaces: /dev/tty[0-9]+ Read Write

Currently looking for an interface which would give me access to read/write to
/dev/tty[0-9]+ to either just present information or even run a “Console UI” in one of the tty consoles.
Below just demonstrate an attempt to write to “/dev/tty2” within a snap.

Test Script

#!/bin/bash
echo -ne "TEST CONTENT\n" > /dev/tty2

Looking in the source of snapd i noticed that “ppp”
seems like the best option to be able to access the /dev/tty[0-9]+
but also tried ofono,waylan,x11 and modem-manager since they have apparmor profiles related to /dev/tty[0-9].

$ snap interfaces testapp
Slot            Plug
:modem-manager  testapp
:ofono          testapp
:ppp            testapp
:wayland        testapp
:x11            testapp
-               testapp:mir

Above test script works in classic/devmode but not in strict mode.
I tested this both on a Ubuntu Server 18 and Ubuntu Core 18 Gadget.

Tested this on “Ubuntu Server 18” only to be able to get the feedback from "snappy-debug.secuirty scanlog ".

snappy-debug output during execution

= AppArmor =
...
Log: apparmor="ALLOWED" operation="open" profile="snap.testapp.testapp" name="/dev/tty2" pid=9941 comm="testapp" requested_mask="wc" denied_mask="wc" fsuid=0 ouid=0
File: /dev/tty2 (write)
Suggestion:
* add 'serial-port (with gadget or core support)' to 'plugs'

Added serial-port interface in my Gadget Snap + Testapp in the same way as I do when I need access to
serial interfaces /dev/ttyS[0-9]+.

Gadget Snap
############
gadget.yaml

...
connections:
    - plug: <snap id>:serial-port
      slot: <gadget snap id>:serialtty-0
    - plug: <snap id>:serial-port
      slot: <gadget snap id>:tty-2

snapcraft.yaml

...
slots:
  serialtty-0:
    interface: serial-port
    path: /dev/ttyS0
  tty-2:
    interface: serial-port
    path: /dev/tty2
...

But I’m still unable give the snap access to one of the tty console, in this case /dev/tty2 (tty-2).

$ snap interfaces testgadget
Slot                    Plug
testgadget:serialtty-0  testapp:testgadget

$sudo journalctl -u snap.testapp.testapp -f
testapp.testapp[3768]: /snap/testapp/x1/usr/bin/testapp: line 2: /dev/tty2: Operation not permitted

Does snapd provide any interface to similar to serial-port but for “dev/tty[0-9]”?

Hi,

The serial-port interface doesn’t work with /dev/tty[0-9] because its whitelist only allows serial ports that match specific well-known path names (such as /dev/ttyUSBx, /dev/ttyACMx and a few others).

We currently don’t have an interface that you’re after; I think we could have a new interface that leverages hotplug (currently experimental and not enabled by default) and creates slots for all /dev/tty[0-9] (single slot for single instance of tty) found in the system.

What do you think @pedronis ?

1 Like

I think there are reasons why we don’t easily let access /dev/tty[0-9], maybe @jdstrand has input on that

These devices (so called “virtual consoles”) are primarily used for local console logins and by display managers. There are at most 63 of them (https://www.kernel.org/doc/Documentation/admin-guide/devices.txt) since ‘c 4 64’ is /dev/ttyS0). Snaps typically should not have access to these, which is why we’ve been very careful about the accesses that serial-port provides (and one of the reasons why the slot policy of mir, x11 and wayland (which allow these) are restricted). There is a class of applications like ‘write’, ‘wall’, ‘talk’, etc that allow sending messages to users that are logged into consoles, but these have been out of scope for snaps (indeed, we don’t allow these commands in the default template and this is fairly antiquated, a way for the snap to send very official looking messages from the system, and modern systems (eg, verified on Debian and Ubuntu) configure login.defs to use TTYPERM 0600 (which makes the /dev/tty# 0600 on user login) so without the user explicitly typing mesg y (which makes the /dev/tty/# 0620 with group tty), these commands and ones like them don’t work anyway (unless you are root)). Also, an application that has access to /dev/tty# of the user can capture input from that tty for that user. These are the reasons why we setup a devpts newinstance in for pseudo-terminals. There isn’t a similar mechanism for /dev/tty# (though legitimate snaps that want to use these mechanisms wouldn’t want that).

I don’t think that existing interfaces should be extended to include these (via hotplug or not). We could consider a new interface to facilitate the generic “Console UI” use case (perhaps we would want hotplug involved, perhaps not), maybe named “virtual-consoles” for this. It would definitely need manual connection.

Thanks for the long explanation. I agree this would be material for a new interface.