Bug 231172

Summary: [sshd] ssh login fails if server is set sysctl kern.trap_enotcap=1
Product: Base System Reporter: Yuichiro NAITO <naito.yuichiro>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Some People CC: cem, emaste, oshogbo
Priority: --- Keywords: patch
Version: CURRENT   
Hardware: Any   
OS: Any   
See Also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=234793
Attachments:
Description Flags
sshd.patch none

Description Yuichiro NAITO 2018-09-05 08:47:25 UTC
Created attachment 196883 [details]
sshd.patch

Problem
-------

While I'm debugging my program which runs in capability mode on remote machine,
I set sysctl kern.trap_enotcap=1 to make my kernel triggers SIGTRAP when
capability violation occurs.

If I quit a ssh session by accident, I can never ssh login again.

Reason
------

Sshd uses login_getpwclass(3) for authentication, but it is not allowed in
capability mode because of accessing to '/etc/login.conf' and
'${HOME}/.login.conf'. Authentication failure triggers to close ssh session.

Please note that this is not a security problem. Sshd checks login_getpwclass(3)
in several times. One of these checks is sandboxed and fails in capability mode.

And sshd calls auth_timeok(3) after login_getpwcalss(3). In auth_timeok(3),
localtime(3) is called and it opens '/etc/localtime'. This is not allowed
neither.

Reproduce
---------

1. stop sshd
   # service sshd stop

2. set kern.trap_enotcap=1
   # sysctl kern.trap_enotcap=1

3. truss sshd
   # truss -f -o /tmp/sshd.log /usr/sbin/sshd -D

4. ssh login
   $ ssh localhost

5. check the logfile
   $ grep 'capability' /tmp/sshd.log
     6637: lstat("/etc/login.conf",0x7fffffffd850)   ERR#94 'Not permitted in capability mode'

Workaround
----------

Apply the attached `sshd.patch` and rebuild sshd. This patch adds wrapper
function of login_getpwclass(3), and fixes the sandboxed process to call this
function.

Question
--------

I know sshd is a contributed software from OpenSSH project. And it seems
FreeBSD project applies specific patches to sshd. Is my code a part of FreeBSD
specific patches? If so, please review my code.
Comment 1 Mariusz Zaborski freebsd_committer freebsd_triage 2018-09-05 17:01:14 UTC
Could you add the patch to http://reviews.freebsd.org/ ?
Thank you.
Comment 2 Yuichiro NAITO 2018-09-06 01:14:36 UTC
(In reply to Mariusz Zaborski from comment #1)
Created https://reviews.freebsd.org/D17056

It is my first differential on Phabricator.
Please let me know if something missing.
Comment 3 commit-hook freebsd_committer freebsd_triage 2018-10-06 21:33:48 UTC
A commit references this bug:

Author: emaste
Date: Sat Oct  6 21:32:58 UTC 2018
New revision: 339216
URL: https://svnweb.freebsd.org/changeset/base/339216

Log:
  sshd: address capsicum issues

  * Add a wrapper to proxy login_getpwclass(3) as it is not allowed in
    capability mode.
  * Cache timezone data via caph_cache_tzdata() as we cannot access the
    timezone file.
  * Reverse resolve hostname before entering capability mode.

  PR:		231172
  Submitted by:	naito.yuichiro@gmail.com
  Reviewed by:	cem, des
  Approved by:	re (rgrimes)
  MFC after:	3 weeks
  Differential Revision:	https://reviews.freebsd.org/D17128

Changes:
  head/crypto/openssh/auth2.c
  head/crypto/openssh/monitor.c
  head/crypto/openssh/monitor.h
  head/crypto/openssh/monitor_wrap.c
  head/crypto/openssh/monitor_wrap.h
  head/crypto/openssh/sandbox-capsicum.c
  head/crypto/openssh/sshbuf-getput-basic.c
  head/crypto/openssh/sshbuf.h
  head/crypto/openssh/sshd.c
Comment 4 Yuichiro NAITO 2018-10-08 06:45:59 UTC
Thanks for the commit.
This problem has been fixed.
I'll close this PR.
Comment 5 Ed Maste freebsd_committer freebsd_triage 2018-10-09 13:38:03 UTC
Note that we still need to work on upstreaming this change.
Comment 6 Conrad Meyer freebsd_committer freebsd_triage 2018-10-09 16:45:18 UTC
Additionally, des@ posted a nice bugfix for platforms with 32-bit time_t (i386) on one of the mailing lists.  Basically the timestamps get a sshbuf_get/put_time instead of using _u64.  And the get/put_time are just macros conditionally defined based on the size of time_t.

I'm not sure if any other mainstream platform openssh runs on uses 32-bit time_t.
Comment 7 Yuichiro NAITO 2018-10-10 11:44:22 UTC
(In reply to Conrad Meyer from comment #6)
I'm sorry that I didn't read CURRENT mailing list.
I subscribed to the mailing list just now.

I understand the problem of size of size_t and time_t on 32bit arm & i386 from mail archives.
I think size_t check caused to print the error message and prevented from more harmful errors.
des@, thank you very much for the quick fix!