[BRLTTY] BRLTTY appears severely broken

Alexander Epaneshnikov aarnaarn2 at gmail.com
Tue Nov 25 22:07:47 UTC 2025


On Tue, Nov 25, 2025 at 04:39:20PM -0500, Dave Mielke wrote:
> [quoted lines by Alexander Epaneshnikov on 2025/11/26 at 00:14 +0300]
>
> >this change was done by systemd in commit https://github.com/systemd/systemd/commit/a4d1891475
>
> I don't know how to read that link. Could you, perhaps, please post the diff?

sure.

$ LC_ALL=.utf8 git --no-pager show a4d1891475
commit a4d1891475
Author: Yu Watanabe <watanabe.yu+github at gmail.com>
Date:   12 months ago

    meson: allow to customize the access mode for tty/pts devices

    Then, switch the default value to "0600", due to general security
    concerns about terminals being written to by other users.

    Closing #35599.

diff --git a/NEWS b/NEWS
index e6baa12c40..7563d63d9c 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,11 @@ CHANGES WITH 258 in spe:

         Incompatible changes:

+        * The default access mode of tty/pts device nodes has been changed to
+          0600, which was 0620 in the older releases, due to general security
+          concerns about terminals being written to by other users. To restore
+          the old default access mode, use '-Dtty-mode=0620' meson build option.
+
         * systemd-run's --expand-environment= switch, which was disabled
           by default when combined with --scope, has been changed to to be
           enabled by default. This brings cmdline expansion of transient
diff --git a/meson.build b/meson.build
index bffda86845..aa51a3aead 100644
--- a/meson.build
+++ b/meson.build
@@ -978,6 +978,16 @@ conf.set10('DEV_KVM_UACCESS', dev_kvm_mode != '0666')
 group_render_mode = get_option('group-render-mode')
 conf.set_quoted('GROUP_RENDER_MODE', group_render_mode)
 conf.set10('GROUP_RENDER_UACCESS', group_render_mode != '0666')
+tty_mode = get_option('tty-mode')
+# The setting is used as both octal integer and string through STRINGIFY().
+# Here, only check if the value starts with '06', and further check will be done in terminal-util.h.
+if not tty_mode.startswith('06')
+        error('Unexpected access mode "@0@" is specified for TTY/PTS device nodes, it must be "06xx".'.format(tty_mode))
+elif tty_mode != '0600' and tty_mode != '0620'
+        warning('Unexpected access mode "@0@" is specified for TTY/PTS device nodes, typically it should be "0600" or "0620", proceeding anyway.'.format(tty_mode))
+endif
+# Do not use set_quoted() here, so that the value is available as an integer.
+conf.set('TTY_MODE', tty_mode)

 kill_user_processes = get_option('default-kill-user-processes')
 conf.set10('KILL_USER_PROCESSES', kill_user_processes)
diff --git a/meson_options.txt b/meson_options.txt
index 78ec25bfa3..d9242d3b30 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -330,6 +330,8 @@ option('dev-kvm-mode', type : 'string', value : '0666',
        description : '/dev/kvm access mode')
 option('group-render-mode', type : 'string', value : '0666',
        description : 'Access mode for devices owned by render group (e.g. /dev/dri/renderD*, /dev/kfd).')
+option('tty-mode', type : 'string', value : '0600',
+       description : 'Access mode for tty/pts device nodes.')
 option('default-kill-user-processes', type : 'boolean',
        description : 'the default value for KillUserProcesses= setting')
 option('gshadow', type : 'boolean',
diff --git a/rules.d/50-udev-default.rules.in b/rules.d/50-udev-default.rules.in
index 6f80feeecf..8fa518cd8f 100644
--- a/rules.d/50-udev-default.rules.in
+++ b/rules.d/50-udev-default.rules.in
@@ -37,7 +37,7 @@ ACTION!="add", GOTO="default_end"

 SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666"
 SUBSYSTEM=="tty", KERNEL=="tty", GROUP="tty", MODE="0666"
-SUBSYSTEM=="tty", KERNEL=="tty[0-9]*|hvc[0-9]*|sclp_line[0-9]*|ttysclp[0-9]*|3270/tty[0-9]*", GROUP="tty", MODE="0620"
+SUBSYSTEM=="tty", KERNEL=="tty[0-9]*|hvc[0-9]*|sclp_line[0-9]*|ttysclp[0-9]*|3270/tty[0-9]*", GROUP="tty", MODE="{{TTY_MODE}}"
 SUBSYSTEM=="vc", KERNEL=="vcs*|vcsa*", GROUP="tty"
 KERNEL=="tty[A-Z]*[0-9]|ttymxc[0-9]*|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"

diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h
index 782b0fed9d..fc7a22e6a5 100644
--- a/src/basic/terminal-util.h
+++ b/src/basic/terminal-util.h
@@ -143,8 +143,9 @@ int vt_release(int fd, bool restore_vt);

 void get_log_colors(int priority, const char **on, const char **off, const char **highlight);

-/* This assumes there is a 'tty' group */
-#define TTY_MODE 0620
+/* Assume TTY_MODE is defined in config.h. Also, this assumes there is a 'tty' group. */
+assert_cc((TTY_MODE & ~0666) == 0);
+assert_cc((TTY_MODE & 0711) == 0600);

 void termios_disable_echo(struct termios *termios);

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 500725d35f..6f90f2f418 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2399,13 +2399,13 @@ static int setup_pts(const char *dest) {
 #if HAVE_SELINUX
         if (arg_selinux_apifs_context)
                 (void) asprintf(&options,
-                                "newinstance,ptmxmode=0666,mode=620,gid=" GID_FMT ",context=\"%s\"",
+                                "newinstance,ptmxmode=0666,mode=" STRINGIFY(TTY_MODE) ",gid=" GID_FMT ",context=\"%s\"",
                                 arg_uid_shift + TTY_GID,
                                 arg_selinux_apifs_context);
         else
 #endif
                 (void) asprintf(&options,
-                                "newinstance,ptmxmode=0666,mode=620,gid=" GID_FMT,
+                                "newinstance,ptmxmode=0666,mode=" STRINGIFY(TTY_MODE) ",gid=" GID_FMT,
                                 arg_uid_shift + TTY_GID);

         if (!options)
diff --git a/src/shared/mount-setup.c b/src/shared/mount-setup.c
index d5009fb59e..73be3b5dce 100644
--- a/src/shared/mount-setup.c
+++ b/src/shared/mount-setup.c
@@ -93,7 +93,7 @@ static const MountPoint mount_table[] = {
 #endif
         { "tmpfs",       "/dev/shm",                  "tmpfs",      "mode=01777",                               MS_NOSUID|MS_NODEV|MS_STRICTATIME,
           NULL,          MNT_FATAL|MNT_IN_CONTAINER },
-        { "devpts",      "/dev/pts",                  "devpts",     "mode=0620,gid=" STRINGIFY(TTY_GID),        MS_NOSUID|MS_NOEXEC,
+        { "devpts",      "/dev/pts",                  "devpts",     "mode=" STRINGIFY(TTY_MODE) ",gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC,
           NULL,          MNT_IN_CONTAINER           },
 #if ENABLE_SMACK
         { "tmpfs",       "/run",                      "tmpfs",      "mode=0755,smackfsroot=*" TMPFS_LIMITS_RUN, MS_NOSUID|MS_NODEV|MS_STRICTATIME,
diff --git a/tools/meson-render-jinja2.py b/tools/meson-render-jinja2.py
index 977de79378..1f893ed9a4 100755
--- a/tools/meson-render-jinja2.py
+++ b/tools/meson-render-jinja2.py
@@ -17,7 +17,9 @@ def parse_config_h(filename):
         if not m:
             continue
         a, b = m.groups()
-        if b and b[0] in '0123456789"':
+        # The function ast.literal_eval() cannot evaluate octal integers, e.g. 0600.
+        # So, it is intentional that the string below does not contain '0'.
+        if b and (b[0] in '123456789"' or b == '0'):
             b = ast.literal_eval(b)
         ans[a] = b
     return ans

> >I pushed fix to archlinux brltty package
> >https://gitlab.archlinux.org/archlinux/packaging/packages/brltty/-/commit/fcb9ae5937575e1df759db92fc828ed76c7586eb
>
> Could you also post your fix?

$ LC_ALL=.utf8 git --no-pager show fcb9ae5937
commit fcb9ae5
Author: Alexander Epaneshnikov <alex19ep at archlinux.org>
Date:   2 hours ago

    fix /dev/tty* permissions

diff --git a/PKGBUILD b/PKGBUILD
index 35f1ca0..2068a68 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -51,15 +51,18 @@ source=(
   $pkgname-6.2-systemd_sysusers_groups.patch
   $pkgname-6.8-lock-brltty-user.patch
   $pkgname-6.4-x11_autostart.patch
+  $pkgname-6.8-udev-tty-perms.rules
 )
 sha512sums=('a7f49850722e65640a3f9690a391d429b3d8658ee55141d9cffc636813ffeedd9eaa1acfa451a0120a9eefcd9b84c6b640eb99aa26357aac9ffda3d48b4fc520'
             '32ba91271e2247b4a330cd213ed75b591268cb99a79c2efd9ae675804faee027c6b2f782768cb2329a65fc914ca2400b2901f35ce1fc2522c6691b343799eb02'
             '2f1dba4fa5495913837972030fbcf1c265c90d481d9e0f96ff89c6cab082f7a6b0594c5c7ca6ea446eb76c8f483c7ed57ede58480898ae003261e6373440862c'
-            '4871512affefbc178f4204a1b285fc2b5a05ea2d181163195d695b760e9729b3d2d00b5f052abd71379df609c3859d7cbd64128bdefd16e898bbc4368500a9a0')
+            '4871512affefbc178f4204a1b285fc2b5a05ea2d181163195d695b760e9729b3d2d00b5f052abd71379df609c3859d7cbd64128bdefd16e898bbc4368500a9a0'
+            'dd210599e467a073f891554c7d3991dce90fa0506a7aef28c43a1543d94073e8d561d36c909511778d4bfcc198cac04f146966edf4462d5e553224a72864f6f3')
 b2sums=('e75b2d0d977f88b61f294226f4e7728ffe0a18592a2b331e63c1d486be909a9e5237c6618151a789b9518f327d8fc2a80a975178201318d9284a399fc0571d42'
         '036e36d558594bb06af1eb41ff5fc9ae52ccf4bad54556c3f4f81a5e2f31f574039835e5e756455527c327a73d563a3db54a9f32e3478545a2a22c2725aaeee2'
         '76fd46571dab803c39a1663e52293c7e1ee9232b6241528e708bca072c7f9bd270c1961b960bece7f91331a259042b8dfc9a8e77f7dc463944b305700fe0c8f6'
-        '4ebc07a725ef8362233a83118e93901e78943e8dae08f9358b668ff13ab88a65eb9e87c49d106a8c3d87eb62007b230e199107eacb01f92dc683335076c01309')
+        '4ebc07a725ef8362233a83118e93901e78943e8dae08f9358b668ff13ab88a65eb9e87c49d106a8c3d87eb62007b230e199107eacb01f92dc683335076c01309'
+        '7110448b42799195abbc6f9711ebe25cdbc95056833764332c343a2d6e1201c8b590644db46a2d6612fa96740cb7da8cc7f72bb329127ae3bb6c8351efcde260')

 prepare() {
   cd $pkgbase-${pkgbase^^}-$pkgver
@@ -143,6 +146,7 @@ package_brltty() {

   # move generic udev rule, as it applies too broadly
   mv -v "$pkgdir/usr/lib/udev/rules.d/90-brltty-usb-generic.rules" ../
+  install -vDm 644 ../brltty-6.8-udev-tty-perms.rules "$pkgdir/usr/lib/udev/rules.d/90-brltty-tty-perms.rules"
 }

 package_brltty-udev-generic() {
diff --git a/brltty-6.8-udev-tty-perms.rules b/brltty-6.8-udev-tty-perms.rules
new file mode 100644
index 0000000..3e77ee4
--- /dev/null
+++ b/brltty-6.8-udev-tty-perms.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0660"

> Does systemd now maintain service units for brltty?

no.

> --
> I believe the Bible to be the very Word of God: http://Mielke.cc/bible/
> Dave Mielke            | 2213 Fox Crescent | WebHome: http://Mielke.cc/
> EMail: Dave at Mielke.cc  | Ottawa, Ontario   | Twitter: @Dave_Mielke
> Phone: +1 613 726 0014 | Canada  K2A 1H7   |
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> http://mielke.cc/xmother.html (Letter from a Feminist ex-Mother)

Sincerely, Alexander


More information about the BRLTTY mailing list