Bug 3448 - heredoc lines get consumed by previous statement
Summary: heredoc lines get consumed by previous statement
Status: CLOSED WORKSFORME
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: sshd (show other bugs)
Version: 8.0p1
Hardware: All Linux
: P5 normal
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-06-17 19:25 AEST by Renaud Métrich
Modified: 2023-03-17 13:41 AEDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Renaud Métrich 2022-06-17 19:25:38 AEST
I don't know if the issue is with bash or sshd, but I believe it's more sshd since the same can be reproduced with zsh but not ksh.

When having a HEREDOC processed through ssh, it appears that any stdin consumer will "eat" the next lines in HEREDOC instead of reading on standard input, as shown in the example below:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
$ ssh -t -t localhost << EOF
tty
cat
echo HELLO
EOF

tty
cat
echo HELLO
[root@vm-rhel8 ~]# tty
/dev/pts/1
[root@vm-rhel8 ~]# cat
echo HELLO
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

Here above the "echo HELLO" should not have been seen since at all, it's written here because it was processed by "cat", and now "cat" continues waiting on stdin for further commands.

I'm expecting this instead, as seen on RHEL7 which has 7.4p1:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
[root@vm-rhel7 ~]# ssh -t -t localhost << EOF
> tty
> cat
> echo HELLO
> EOF

tty
cat
echo HELLO
[root@vm-rhel7 ~]# tty
/dev/pts/1
[root@vm-rhel7 ~]# cat
---> this is "cat" execution waiting on standard input. "echo HELLO" was not processed yet.
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------


With "ksh", this continues working fine:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
$ ssh -t -t localhost ksh << EOF
tty
cat
echo HELLO
EOF
tty
cat
echo HELLO
# 
/dev/pts/1
#
---> this is "cat" execution waiting on standard input. "echo HELLO" was not processed yet.
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

This happens on 8.0p1 and later, including up to 8.8p1 at least.
It seems like that this is due to having non-blocking mode for stdin file descriptor somehow, since using Ctrl-C "breaks" the shell and I need to use "reset" to makes the shell work fine again.

This prevents any HEREDOC to be passed through ssh, as shown in the following "legit" example:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
$ ssh -t -t vm-rhel8 << EOF
systemctl status sshd
echo "RC $?"
exit
EOF
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

HEREDOC execution:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
systemctl status sshd
echo "RC 0"
exit
[root@vm-rhel8 ~]# systemctl status sshd
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset>
   Active: active (running) since Thu 2022-06-16 08:53:15 CEST; 48min ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 896 (sshd)
    Tasks: 1 (limit: 11377)
   Memory: 9.5M
   CGroup: /system.slice/sshd.service
           └─896 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-po>

Jun 16 09:36:25 vm-rhel8 sshd[2832]: pam_unix(sshd:session): session opened for>
Jun 16 09:36:41 vm-rhel8 sshd[2895]: Accepted publickey for root from 192.168.1>
Jun 16 09:36:41 vm-rhel8 sshd[2895]: pam_unix(sshd:session): session opened for>
Jun 16 09:39:19 vm-rhel8 sshd[2958]: Accepted publickey for root from 192.168.1>
Jun 16 09:39:19 vm-rhel8 sshd[2958]: pam_unix(sshd:session): session opened for>
Jun 16 09:39:19 vm-rhel8 sshd[2958]: pam_unix(sshd:session): session closed for>
Jun 16 09:39:39 vm-rhel8 sshd[3026]: Accepted publickey for root from 192.168.1>
Jun 16 09:39:39 vm-rhel8 sshd[3026]: pam_unix(sshd:session): session opened for>
Jun 16 09:41:55 vm-rhel8 sshd[3078]: Accepted publickey for root from 192.168.1>
Jun 16 09:41:55 vm-rhel8 sshd[3078]: pam_unix(sshd:session): session opened for>
...skipping...

                   SUMMARY OF LESS COMMANDS

      Commands marked with * may be preceded by a number, N.
      Notes in parentheses indicate the behavior if N is given.
      A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
...
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

Here above, the "systemctl status sshd" command spawns the pager which reads the next line ("echo "RC $?"") and processes it as "pager" commands, which ends up bipping and displaying "pager" help.
Comment 1 Damien Miller 2022-06-24 13:43:38 AEST
AFAIK it's the shell that is getting confused. ssh is propagating the stdin close correctly from the client:

> debug2: PTY allocation request accepted on channel 0
> debug2: channel 0: rcvd adjust 2097152
> debug3: receive packet: type 99
> debug2: channel_input_status_confirm: type 99 id 0
> debug2: shell request accepted on channel 0
> debug2: channel 0: read<=0 rfd 4 len 0: closed
> debug2: channel 0: read failed
> debug2: chan_shutdown_read: channel 0: (i0 o0 sock -1 wfd 4 efd 6 [write])

to the server:

> Starting session: shell on pts/7 for djm from 127.0.0.1 port 37500 id 0
> debug2: fd 3 setting TCP_NODELAY
> debug3: set_sock_tos: set socket 3 IP_TOS 0x48
> debug2: channel 0: rfd 8 isatty
> debug2: fd 8 setting O_NONBLOCK
> debug3: fd 6 is O_NONBLOCK
> debug3: send packet: type 99
> debug1: Setting controlling tty using TIOCSCTTY.
> debug3: receive packet: type 96
> debug2: channel 0: rcvd eof
> debug2: channel 0: output open -> drain
> debug2: channel 0: obuf empty
> debug2: chan_shutdown_write: channel 0: (i0 o1 sock -1 wfd 6 efd -1 [closed])
> debug2: channel 0: output drain -> closed

It's possible that bash/zsh is getting confused by its stdin being nonblock, but there isn't much that ssh/sshd can do about that without reintroducing bug #3280

It does seem to behave better when a PTY is not requested (i.e. remove the -t flags)
Comment 2 Damien Miller 2023-03-17 13:41:33 AEDT
OpenSSH 9.3 has been released. Close resolved bugs