Bug 2140 - Capsicum support for FreeBSD 10 (-current)
Summary: Capsicum support for FreeBSD 10 (-current)
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: sshd (show other bugs)
Version: -current
Hardware: All FreeBSD
: P5 enhancement
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks: V_6_5
  Show dependency treegraph
 
Reported: 2013-08-08 05:54 AEST by Loganaden Velvindron
Modified: 2016-08-02 10:42 AEST (History)
2 users (show)

See Also:


Attachments
openssh-capsicum (5.29 KB, text/plain)
2013-08-08 05:54 AEST, Loganaden Velvindron
no flags Details
capsicum (6.30 KB, patch)
2013-10-13 17:54 AEDT, Loganaden Velvindron
no flags Details | Diff
capsicum (6.58 KB, patch)
2013-10-23 03:08 AEDT, Loganaden Velvindron
no flags Details | Diff
capsicum (10.12 KB, patch)
2013-10-25 05:46 AEDT, Loganaden Velvindron
no flags Details | Diff
FreeBSD 10-BETA2 (10.11 KB, patch)
2013-11-01 21:37 AEDT, Loganaden Velvindron
no flags Details | Diff
FreeBSD 10 RC3 (10.10 KB, patch)
2013-12-31 22:04 AEDT, Loganaden Velvindron
no flags Details | Diff
minor nits for capsicum (1.07 KB, patch)
2014-01-18 00:11 AEDT, Loganaden Velvindron
no flags Details | Diff
disable setrlimit(RLIMIT_NOFILE, 0) (924 bytes, patch)
2014-01-25 17:25 AEDT, Loganaden Velvindron
no flags Details | Diff
minor fixes (870 bytes, patch)
2014-02-04 18:28 AEDT, Loganaden Velvindron
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Loganaden Velvindron 2013-08-08 05:54:20 AEST
Created attachment 2326 [details]
openssh-capsicum

Recently, I started playing around with FreeBSD 10.

Following a discussion on capsicum-mailing:

https://lists.cam.ac.uk/pipermail/cl-capsicum-discuss/2013-August/msg00000.html

I took pjd@ and des@ patches for the older openssh in freebsd-base, and started working on implementing it on openssh-current.

The only change I made is use extern for pmonitor.

The patch works fine when I try to use connect() in the child process as it fails, as connect() isn't listed in capabilities.conf.

It's still a WiP as capsicum is still a moving target.

Feedback appreciated.
Comment 1 Damien Miller 2013-10-10 11:24:47 AEDT
Comment on attachment 2326 [details]
openssh-capsicum

Looks good - a couple of small things.

>Index: sandbox-capsicum.c
>===================================================================
>RCS file: sandbox-capsicum.c
>diff -N sandbox-capsicum.c
>--- /dev/null	1 Jan 1970 00:00:00 -0000
>+++ sandbox-capsicum.c	7 Aug 2013 19:39:21 -0000
>@@ -0,0 +1,90 @@
>+

Please add a license block here. http://www.openbsd.org/cgi-bin/cvsweb/src/share/misc/license.template?rev=1.3;content-type=text%2Fplain is our preferred one.

>+/* Capsicum sandbox that sets zero nfiles, nprocs and filesize rlimits,
>+ * limits file descriptors on monitoring object,
>+ * and switches to capability mode
>+*/

Minor style nit. The first line of a multiline comment should be "/*" by itself.
The last line's '*' should be aligned to the previous line's (i.e. add a space at the start of the line).

>+struct ssh_sandbox {
>+	struct monitor *monitor;

This isn't used and can be removed.

>+extern struct monitor *pmonitor;

This can go too.

>+	box->monitor = pmonitor;

and this.


>+	if (cap_rights_limit(box->monitor->m_recvfd, CAP_READ | CAP_WRITE) == -1)
>+		fatal("%s: failed to limit the network socket", __func__);
>+	if (cap_rights_limit(box->monitor->m_log_sendfd, CAP_WRITE) == -1)
>+		fatal("%s: failed to limit the logging socket", __func__);

Are there any other fds open at this point? How about 0, 1 and 2 - could they be limited?
Comment 2 Damien Miller 2013-10-10 11:25:07 AEDT
Put this on the map for 6.4
Comment 3 Loganaden Velvindron 2013-10-13 17:50:59 AEDT
(In reply to Damien Miller from comment #1)
> Comment on attachment 2326 [details]
> openssh-capsicum
> 
> Looks good - a couple of small things.
> 
> >Index: sandbox-capsicum.c
> >===================================================================
> >RCS file: sandbox-capsicum.c
> >diff -N sandbox-capsicum.c
> >--- /dev/null	1 Jan 1970 00:00:00 -0000
> >+++ sandbox-capsicum.c	7 Aug 2013 19:39:21 -0000
> >@@ -0,0 +1,90 @@
> >+
> 
> Please add a license block here.
> http://www.openbsd.org/cgi-bin/cvsweb/src/share/misc/license.
> template?rev=1.3;content-type=text%2Fplain is our preferred one.

The diff is based on an older patch for OpenSSH written by des@freebsd.

http://people.freebsd.org/~pjd/patches/openssh-capsicum.patch

I added his copyright.

> 
> >+/* Capsicum sandbox that sets zero nfiles, nprocs and filesize rlimits,
> >+ * limits file descriptors on monitoring object,
> >+ * and switches to capability mode
> >+*/
> 
> Minor style nit. The first line of a multiline comment should be
> "/*" by itself.

Corrected.

> The last line's '*' should be aligned to the previous line's (i.e.
> add a space at the start of the line).
> 
> >+struct ssh_sandbox {
> >+	struct monitor *monitor;
> 
> This isn't used and can be removed.
> 
> >+extern struct monitor *pmonitor;
> 
> This can go too.
> 
> >+	box->monitor = pmonitor;
> 
> and this.
> 

Removed and tested on FreeBSD 10 ALPHA.

> 
> >+	if (cap_rights_limit(box->monitor->m_recvfd, CAP_READ | CAP_WRITE) == -1)
> >+		fatal("%s: failed to limit the network socket", __func__);
> >+	if (cap_rights_limit(box->monitor->m_log_sendfd, CAP_WRITE) == -1)
> >+		fatal("%s: failed to limit the logging socket", __func__);
> 
> Are there any other fds open at this point? How about 0, 1 and 2 -
> could they be limited?

Yep, we can limit them completely.

No read and write possible on 0,1 & 2.
Comment 4 Loganaden Velvindron 2013-10-13 17:54:34 AEDT
Created attachment 2352 [details]
capsicum

Tested on FreeBSD 10 Alpha 5
Comment 5 Damien Miller 2013-10-14 15:11:44 AEDT
Comment on attachment 2352 [details]
capsicum

This looks good to me. Darren can give a second opinion.
Comment 6 Loganaden Velvindron 2013-10-14 18:45:03 AEDT
(In reply to Damien Miller from comment #5)
> Comment on attachment 2352 [details]
> capsicum
> 
> This looks good to me. Darren can give a second opinion.

I'll keep in sync with FreeBSD 10 development branch as changes are made to capsicum to make sure that the patch works. FreeBSD 10 is slated to be released around the 24th of November.

Thank you for reviewing this fairly large diff :-)
Comment 7 Loganaden Velvindron 2013-10-23 01:47:51 AEDT
Hold on with the patch.

There are issues with it on the latest builds. Capsicum had been changed recently, and it looks like the patch no longer works as expected.
Comment 8 Loganaden Velvindron 2013-10-23 03:08:12 AEDT
Created attachment 2364 [details]
capsicum

We need to reference pmonitor in sshd.c.

I used extern and then assigned it to box->monitor.

Alternatively, we can use des & pjd's approach which is to pass the monitor struct in ssh_sandbox_init(struct monitor), and then limits the descriptors rights.

What do you guys think ?
Comment 9 Damien Miller 2013-10-23 14:25:48 AEDT
Comment on attachment 2364 [details]
capsicum

>+struct ssh_sandbox {
>+	struct monitor *monitor;
>+	pid_t child_pid;
>+};
>+
>+extern struct monitor *pmonitor;
>+struct ssh_sandbox *
>+ssh_sandbox_init(void)
>+{
>+	struct ssh_sandbox *box;
>+
>+	/*
>+	 * Strictly, we don't need to maintain any state here but we need
>+	 * to return non-NULL to satisfy the API.
>+	 */
>+	debug3("%s: preparing capsicum sandbox", __func__);
>+	box = xcalloc(1, sizeof(*box));
>+	box->monitor = pmonitor;

I think it would be a better idea to just record the fd numbers themselves in the struct rather than the monitor address.
Comment 10 Damien Miller 2013-10-24 10:29:46 AEDT
(In reply to Loganaden Velvindron from comment #8)
> Alternatively, we can use des & pjd's approach which is to pass the
> monitor struct in ssh_sandbox_init(struct monitor), and then limits
> the descriptors rights.

Sorry, I missed this comment. Yes, I think passing the pointer to the monitor is a good idea. Then ssh_sandbox_init() can store the fd numbers from it.
Comment 11 Loganaden Velvindron 2013-10-25 05:46:55 AEDT
Created attachment 2365 [details]
capsicum
Comment 12 Loganaden Velvindron 2013-10-25 05:47:45 AEDT
(In reply to Damien Miller from comment #10)
> (In reply to Loganaden Velvindron from comment #8)
> > Alternatively, we can use des & pjd's approach which is to pass the
> > monitor struct in ssh_sandbox_init(struct monitor), and then limits
> > the descriptors rights.
> 
> Sorry, I missed this comment. Yes, I think passing the pointer to
> the monitor is a good idea. Then ssh_sandbox_init() can store the fd
> numbers from it.

Modified as requested.
Comment 13 Loganaden Velvindron 2013-11-01 21:37:13 AEDT
Created attachment 2371 [details]
FreeBSD 10-BETA2

Tested on latest FreeBSD 10 BETA 2 snapshot.

Diff was adjusted slightly based on latest changes.
Comment 14 Loganaden Velvindron 2013-11-02 21:21:13 AEDT
ping6 dtucker :-) ?
Comment 15 Loganaden Velvindron 2013-11-10 02:06:56 AEDT
ping6 ?
Comment 16 Loganaden Velvindron 2013-12-31 22:03:00 AEDT
Adjusted the diff for FreeBSD 10 RC3 release which is going to be released on the 3rd of January.
Comment 17 Loganaden Velvindron 2013-12-31 22:04:14 AEDT
Created attachment 2397 [details]
FreeBSD 10 RC3

Tested on FreeBSD 10 RC3
Comment 18 Loganaden Velvindron 2014-01-11 19:48:02 AEDT
Tested on FreeBSD 10 RC 4
Comment 19 Loganaden Velvindron 2014-01-11 23:11:41 AEDT
Tested on FreeBSD 10RC5
Comment 20 Loganaden Velvindron 2014-01-13 14:21:58 AEDT
As discussed with the FreeBSD developers, no more API changes. FreeBSD 10 RC5 is the last RC. Assuming no showstopper, it's going to be released as it is.
Comment 21 Damien Miller 2014-01-17 16:49:49 AEDT
Patch applied. This will be in OpenSSH-6.5 - thanks!
Comment 22 Loganaden Velvindron 2014-01-18 00:11:50 AEDT
Created attachment 2398 [details]
minor nits for capsicum

-Fix descriptions for stdin and stdout in error paths.

- use < 0 when calling cap_enter() so that it matches what dhclient and other demons are doing on FreeBSD.
Comment 23 Darren Tucker 2014-01-18 22:12:23 AEDT
also applied, thanks.
Comment 24 Loganaden Velvindron 2014-01-24 23:44:32 AEDT
There's still an issue. I'll upload a new diff in a few hours.
Comment 25 Loganaden Velvindron 2014-01-25 17:24:26 AEDT
As discussed with pjd@FreeBSD:

There's an issue on FreeBSD where a CRIOGET ioctl is failing due to setrlimit applied with NOFILE.

The commit message is not correct.

From:
http://svnweb.freebsd.org/base/head/crypto/openssh/servconf.c?view=log&pathrev=251088

Revert a local change that sets the default for UsePrivilegeSeparation to
"sandbox" instead of "yes".  In sandbox mode, the privsep child is unable
to load additional libraries and will therefore crash when trying to take
advantage of crypto offloading on CPUs that support it.

So comment it for now.
Comment 26 Loganaden Velvindron 2014-01-25 17:25:43 AEDT
Created attachment 2401 [details]
disable setrlimit(RLIMIT_NOFILE, 0)
Comment 27 Loganaden Velvindron 2014-02-04 18:28:47 AEDT
Created attachment 2405 [details]
minor fixes

make the return value check for cap_rights_limit() consistent with the man pages and also include a proper check for errno.

Discussed with Pawel J Dawidek (pjd@freebsd.org) and based on his diff.
Comment 28 Damien Miller 2014-02-05 10:34:10 AEDT
applied - thanks
Comment 29 Damien Miller 2016-08-02 10:42:54 AEST
Close all resolved bugs after 7.3p1 release