1

When connecting from PC/Cygwin via SSH (over WiFi) to phone, I am always greeted with the following macabre message:

$ ssh -T root@192.168.1.100 -p 50000
Authenticated with partial success.
root@192.168.1.100's password:
/system/bin/sh: No controlling tty: open /dev/tty: No such device or address
/system/bin/sh: can't find tty fd
/system/bin/sh: warning: won't have full job control
root@android:/ $

I know the device is there, and I have also tried various chmod permissions.

The problem is that I cannot use stty (or anything related to ttys) to set my terminal environment variables, and therefore I cannot use command line TAB completion or arrow-up, to fetch last command, or using CTRL-C/D/Z etc. I've also tried to play with various set -o options, to no avail.

Now the strange thing is that this problem is not at all present when using a local shell through the Android terminal Emulator app, which seem to correctly assign a pseudo terminal with full job control.

I've been searching high and low for how to resolve this, but gotten nowhere. My Samsung phone is using an SELinux (AOS 4.2.2) enabled version and I'm rooted with CF-Auto-Root (v1.94), and using the latest ADB. The stock mksh is @(#)MIRBSD KSH R40 2011/10/07 and thus perhaps not fully compatible with SEL AOS's, but I cannot find a newer (~R49) MKSH ARM binary, to try with.


EDIT-1: I am using SSH server.

EDIT-2: I just tried SSHelper which seem very nice (although 6 x larger). But it is unstable and show similar issues in the web log: PTY allocation request failed on channel 0

EDIT-3: After login (with new sshd server) with: ssh -T dummy@192.168.1.10 -p 2222, I loose prompt, but shell access is still ok. then running su -c /system/bin/sh -i give me back the correct su prompt # and checking set -o gives:

u0_a202@MSM8960:home # set -o
Current option settings
allexport      off  login          off  nounset        off  verbose        off
bgnice         off  markdirs       off  physical       off  vi             off
braceexpand    on   monitor        on   posix          off  vi-esccomplete off
emacs          on   noclobber      off  privileged     off  vi-tabcomplete on
errexit        off  noexec         off  restricted     off  viraw          off
gmacs          off  noglob         off  sh             off  xtrace         off
ignoreeof      off  nohup          on   stdin          on
interactive    on   nolog          off  trackall       off
keyword        off  notify         off  utf8-mode      off

But TAB is still directly interpreted as a TAB character and not command-line completion.

EDIT-4: This must be a SELinux / SEAndroid related issue, as when I disable SELinux Enforcing by setting it to Permissive, I loose the ability to SU, but all normal shell terminal controls are working. The way to do this is by issuing: su 0 setenforce 0 in whatever shell you can get, and then logout and login again. This will last until you reboot phone.

EDIT-5: From what I understand, using the ssh -t option, is used to force allocation of a pseudy-terminal, and terminates the connection if that fails. Thus it fails when pty is blocked in "Enforcing" mode, while using ssh -2 is accepted with minimal difference in error when using -vvv to debug.

$ ssh -t dummy@192.168.1.10 -p 2222 -vvv
...
dummy@192.168.1.10's password:
debug3: packet_send2: adding 64 (len 51 padlen 13 extra_pad 64)
debug2: we sent a password packet, wait for reply
debug1: Authentication succeeded (password).
Authenticated to 192.168.1.10 ([192.168.1.10]:2222).
debug1: channel 0: new [client-session]
debug3: ssh_session2_open: channel_new: 0
debug2: channel 0: send open
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug2: callback start
debug2: fd 3 setting TCP_NODELAY
debug3: packet_set_tos: set IP_TOS 0x10
debug2: client_session2_setup: id 0
debug2: channel 0: request pty-req confirm 1
debug2: channel 0: request shell confirm 1
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel_input_status_confirm: type 100 id 0
PTY allocation request failed on channel 0

Not accepted, but this next one give me a shell without any prompt.

$ ssh -2 dummy@192.168.1.10 -p 2222 -vvv
...
PTY allocation request failed on channel 0
debug2: channel 0: rcvd adjust 2097152
debug2: channel_input_status_confirm: type 99 id 0
debug2: shell request accepted on channel 0
Linux 3.4.0-2340422 armv7l

This behavior is convincing me to think it is directly related to the SELinux blocking pty access. But I have no idea how and where this is done.

EDIT-6: Yep, there it is. I just found the SELinux policy denial in the audit.log file in: /data/misc/audit/audit.log

audit(1401291488.480:203): avc:  denied  { setattr } for  pid=11441 comm="sshelper_sshd" name="0" dev="devpts" ino=3 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:untrusted_app_devpts:s0 tclass=chr_file VE=SEPF_GT-I9195_4.2.2_0022_M
audit(1401291488.480:203): arch=40000028 syscall=15 per=840000 success=no exit=-13 a0=beffd438 a1=190 a2=27da a3=c0000000 items=1 ppid=8499 pid=11441 auid=4294967295 uid=10202 gid=10202 euid=10202 suid=10202 fsuid=10202 egid=10202 sgid=10202 fsgid=10202 tty=(none) ses=4294967295 comm="sshelper_sshd" exe="/data/data/com.arachnoid.sshelper/bin/sshelper_sshd" subj=u:r:untrusted_app:s0 key=(null)
audit(1401291488.480:203):  cwd="/"
audit(1401291488.480:203): item=0 name="/dev/pts/0" inode=3 dev=00:09 mode=020600 ouid=10202 ogid=10202 rdev=88:00 obj=u:object_r:untrusted_app_devpts:s0

So how to fix this?

  • Might be some trouble caused by the sshd on the device, which cannot deal with that properly? You've missed to include information on which one that is. Maybe try a different one? – Izzy May 25 '14 at 16:54
  • 1
    @Izzy: Added link and will try another one. – not2qubit May 25 '14 at 17:30
  • There seem to be something changed in recent Androids that prevents ssh from getting a (pts) pseudo tty. – not2qubit May 27 '14 at 9:13
  • I wouldn't wonder. Every new Android version comes with some, umm, "surprises" included … But if that's the cause, others would be affected too (confirmations, please?). 4.2.2 is not "that new" anymore. – Izzy May 27 '14 at 11:09
  • Hm. Only thing I can find about SELinux for Android. It does have some information on changing the SELinux policy though this appears to involve rebuilding some part of it… maybe contact its developers and ask for help? Also, did you ask the SSH developer? (Of course, switching to permissive would fix this.) – mirabilos May 30 '14 at 16:55
2

You are using ssh -T which prevents tty(4) allocation. Without a controlling tty, many things do not work – without any tty at all, a lot more things do not work.

Do note that your original problem is not due to the lack of a controlling tty, but due to the lack of a pty/tty pair allocation.

What you are having here is basically input line “editing” – in your case, not-editing – on the SSH client side, which is then transferred over ssh to the Android device.

Try with ssh -t (lower-case t, note the difference). I can locally reproduce your problem by running ssh -T localhost mksh -i, which also leads to a shell without any input line editing, so pty/tty allocation is the way to solve, here.

I assume, from the edits on the question, that /dev/ptmx exists and /dev/pts is mounted already, and that this is an SELinux problem.

Setting $TERM will solve nothing here: it is merely there to tell programs that use termcap or curses (mksh uses neither) which physical terminal (or emulation thereof) is connected to the tty device. mksh uses a tty for command line editing if it's there, and disables command line editing if it's not there.

You need to edit your SELinux policies to allow the SSH server to allocate a pty/tty pair (or even several ones) per connection.

(This answer has been edited to fold in the comments from this and the original question, and to reflect some edits to the question.)

  • Yes, that was one the first things I did, but then I decided to use -T to avoid the pty problem, by passing a TERM variable manually. Perhaps wrong? Anytime I give the -t switch, ssh accepts password and then fails, because of permission to open pty, with PTY allocation request failed on channel 0. However, using -2 (ssh2) lets me through. – not2qubit May 28 '14 at 0:49
  • Thanks for clarifying. Cygwin is not the problem, I've used it for years and it always works as expected. I'm now sure it's an SELinux policy problem, since the author of SSHelper was using CyanogenMod for development and is thus not used to SELinux policies either and probably have not implemented it correctly. (None of the free SSHd Android apps has.) Any idea where to find the policy files and how to edit them? – not2qubit May 28 '14 at 15:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.