]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
meson: allow to customize the access mode for tty/pts devices
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 16 Dec 2024 02:50:53 +0000 (11:50 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 8 Feb 2025 06:51:06 +0000 (15:51 +0900)
Then, switch the default value to "0600", due to general security
concerns about terminals being written to by other users.

Closing #35599.

Backport note: the default is changed back to 0620 to keep backward
compatbility intact for the purpose of backporting. This lets
security-conscious users fix  the issue if they want to, without
affecting users that do not want changes in the stable branches.

(cherry picked from commit a4d18914751e687c9e44f22fe4e5f95b843a45c8)

meson.build
meson_options.txt
rules.d/50-udev-default.rules.in
src/basic/terminal-util.h
src/nspawn/nspawn.c
src/shared/mount-setup.c
tools/meson-render-jinja2.py

index caf2af0753da629da10f9c8fb59cee845053108e..cfb202eb30aa4380ceab76b2f2f6958c3ecbf41d 100644 (file)
@@ -987,6 +987,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)
index 78ec25bfa3c4b57b33135b84e3a1f04bc5279faa..f30b3f52389440a7b14199d1267cdf12e470e20c 100644 (file)
@@ -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 : '0620',
+       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',
index 6f80feeecf8ffe367f1bdc809d9a5f59c0175381..8fa518cd8f92152cd9138d6c120e2f9bafe01e15 100644 (file)
@@ -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"
 
index 90662e2e660cdb14338e685c2e20d00f33ef6b01..2fb5281a53a2cc957ff761a2b1da213055d061e3 100644 (file)
@@ -144,8 +144,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);
 
index 500725d35f651346cbee16c0fca2a4b45b6a5bb9..6f90f2f418d2954ce784ab9de213275631260a50 100644 (file)
@@ -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)
index d5009fb59ed158da8017f197e817c693c8f85266..73be3b5dce72473acaeb3cb0282f8f5537945960 100644 (file)
@@ -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,
index 977de79378a96c1e528ce6ca4ea7a2fe4caae259..1f893ed9a429289779593034c54d39c725442055 100755 (executable)
@@ -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