[Bug 9231] New: less should fall back to stdout fd

bugzilla at busybox.net bugzilla at busybox.net
Mon Sep 12 21:45:45 UTC 2016


https://bugs.busybox.net/show_bug.cgi?id=9231

            Bug ID: 9231
           Summary: less should fall back to stdout fd
           Product: Busybox
           Version: unspecified
          Hardware: All
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P5
         Component: Other
          Assignee: unassigned at busybox.net
          Reporter: vapier at gentoo.org
                CC: busybox-cvs at busybox.net
  Target Milestone: ---

if the active tty is inaccessible by re-opening, then less fails to get the
right terminal settings, so it falls back to bb_cat().  this shouldn't be
necessary though as we already have the open stdout fd available to us.

there's this comment in the code:
    /* Some versions of less can survive w/o controlling tty,
     * try to do the same. This also allows to specify an alternative
     * tty via "less 1<>TTY".
     * We don't try to use STDOUT_FILENO directly,
     * since we want to set this fd to non-blocking mode,
     * and not bother with restoring it on exit.
     */

except this doesn't make sense -- the fd passed to it is a dup from a parent,
so any changes busybox makes to the file status flags via fcntl of its copy
doesn't impact other processes.  when it exits, its fd simply goes away.

you might have to worry about changing things if less created children, but it
doesn't currently support the ! command, so that doesn't come up.  what
scenario is of concern here ?

the reason i bring this up is that busybox's less fails to work when both the
controlling tty and /dev/tty nodes are inaccessible.  this comes up when using
something like `su` to change uid from root to nobody (and /dev/pts/# is
root:tty with 620 perms), and a tool creates a new session like setsid() (which
means opening /dev/tty returns ENXIO).  shadow's `su` implementation currently
does exactly that:

# su -s /bin/sh -c 'echo hi >/dev/tty' - nobody
-su: 1: cannot create /dev/tty: No such device or address

# su -s /bin/sh -c 'busybox less /proc/filesystems' - nobody
<falls through to bb_cat>

# su -s /bin/sh -c 'strace -eopen busybox less /proc/filesystems' - nobody 
open("/dev/pts/19", O_RDONLY)           = -1 EACCES (Permission denied)
open("/dev/tty", O_RDONLY)              = -1 ENXIO (No such device or address)
open("/proc/filesystems", O_RDONLY)     = 3

i'd imagine an easy fix would be:

--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -1781,9 +1781,6 @@ int less_main(int argc, char **argv)
    /* Some versions of less can survive w/o controlling tty,
     * try to do the same. This also allows to specify an alternative
     * tty via "less 1<>TTY".
-    * We don't try to use STDOUT_FILENO directly,
-    * since we want to set this fd to non-blocking mode,
-    * and not bother with restoring it on exit.
     */
    tty_name = xmalloc_ttyname(STDOUT_FILENO);
    if (tty_name) {
@@ -1796,7 +1793,7 @@ int less_main(int argc, char **argv)
  try_ctty:
        tty_fd = open(CURRENT_TTY, O_RDONLY);
        if (tty_fd < 0)
-           return bb_cat(argv);
+           tty_fd = STDOUT_FILENO;
    }
    ndelay_on(tty_fd);
    kbd_fd = tty_fd; /* save in a global */

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the busybox-cvs mailing list