bash randomly logs out on VT / serial console

2017-01-01 Thread rmk
Configuration Information [Automatically generated, do not change]:
Machine: aarch64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='aarch64' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='aarch64-unknown-linux-gnu' 
-DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' 
-DSHELL -DHAVE_CONFIG_H   -I.  -I../. -I.././include -I.././lib  
-D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector-strong -Wformat 
-Werror=format-security -Wall
uname output: Linux mcbin 4.9.0+ #249 SMP PREEMPT Sun Jan 1 17:28:33 GMT 2017 
aarch64 aarch64 aarch64 GNU/Linux
Machine Type: aarch64-unknown-linux-gnu

Bash Version: 4.3
Patch Level: 30
Release Status: release

Description:
Running:
while :; do s=$(sleep .005 | cat); echo $s; done | uniq
in a login shell on a virtual terminal or serial console results
in the shell randomly logging out after ^C.

Debugging reveals that:
(a) the top-level shell sets the terminal PGRP and current process
 group to the shell's process ID (shell_pgrp as bash calls it).
 However, when bash gets around to reading input, it receives an
 EIO error - kernel debugging shows that this is because the TTY
 PGRP does not match the processes PGRP at this point.
(b) the sub-shell running the "while" does not wait for the $(...)
 to finish before sending itself a SIGINT.
(c) the sub-sub-shell for the $(...) waits for the "sleep" command
 to terminate, and then sets the PGRP and current process group to
 original_pgrp, which is the login process ID.

stracing the shell (strace -tt -ff -o str.bash -p )
and grepping the resulting log files for SPGRP shows:

str.bash.10928:17:38:38.745323 ioctl(255, TIOCGPGRP, [14119]) = 0
str.bash.10928:17:38:39.478119 ioctl(255, TIOCSPGRP, [10928]) = 0
str.bash.10928:17:38:39.480458 ioctl(255, TIOCSPGRP, [10928]) = 0
str.bash.10928:17:38:39.902027 ioctl(255, TIOCSPGRP, [10875]) = 0
str.bash.14119:17:38:38.719282 ioctl(255, TIOCSPGRP, [14119]) = 0
str.bash.14119:17:38:39.476968 ioctl(255, TIOCSPGRP, [10875]) = 0
str.bash.14120:17:38:38.718508 ioctl(255, TIOCSPGRP, [14119]) = 0
str.bash.14241:17:38:39.485459 ioctl(255, TIOCSPGRP, [10875]) = 0
str.bash.14243:17:38:39.477927 ioctl(255, TIOCSPGRP, [10875]) = 0

and stracing the login shell for terminal IO:
str.bash.10928:17:38:39.482909 write(2, "root@mcbin:~# ", 14) = 14
str.bash.10928:17:38:39.483027 read(0, "\33", 1)   = 1
str.bash.10928:17:38:39.870424 read(0, 0x7fc81f8737, 1) = -1 EIO (Input/output 
error)
str.bash.10928:17:38:39.884115 write(2, "\7", 1)   = 1
str.bash.10928:17:38:39.884212 read(0, 0x7fc81f87a7, 1) = -1 EIO (Input/output 
error)
str.bash.10928:17:38:39.899960 write(2, "logout\n", 7) = 7

From the timestamps, you can see that PID 14241 changed the TTY
PGRP between the write-out of the prompt, reading the first
character of input, and attempting to read the subsequent
characters - resulting in the shell logging itself out.

Here, pid 10875 was the login process.

Adding debug into give_terminal_to() changes the timing enough
that it becomes very difficult to trigger.  Remove the debug and
it seems to be soo easy that bash is painful to use on such a
terminal.

(My command which discovered this was slightly more complex and
 useful than the above, but the above is a simpler test case
 which reproduces the problem.)

Repeat-By:
Login on a serial console.  Probably logging in on a Linux
virtual terminal will also be good enough.  Not a SSH connection,
there needs to be a login(8) process as bash's parent.

Run:
  while :; do s=$(sleep .005 | cat); echo $s; done | uniq

Hit ^c.  Repeat a few times.  Tested on a quad-core ARM64 machine
and a dual-core 32-bit ARM machine.



Re: bash randomly logs out on VT / serial console

2017-01-01 Thread Chet Ramey
On 1/1/17 4:01 PM, r...@armlinux.org.uk wrote:
> Bash Version: 4.3
> Patch Level: 30
> Release Status: release
> 
> Description:
>   Running:
>   while :; do s=$(sleep .005 | cat); echo $s; done | uniq
>   in a login shell on a virtual terminal or serial console results
>   in the shell randomly logging out after ^C.

I believe this is fixed in bash-4.4.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/