Bug 211580 - deny system message buffer access from jails
Summary: deny system message buffer access from jails
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-jail mailing list
URL:
Keywords: patch, security
Depends on:
Blocks:
 
Reported: 2016-08-04 15:26 UTC by Bjoern A. Zeeb
Modified: 2018-10-20 16:23 UTC (History)
8 users (show)

See Also:


Attachments
Patch to allow per-jail msgbuf access (4.86 KB, patch)
2016-08-08 21:44 UTC, Bjoern A. Zeeb
no flags Details | Diff
Current revision of allow.read_msgbuf patch (4.81 KB, patch)
2018-10-14 05:56 UTC, Jamie Gritton
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Bjoern A. Zeeb freebsd_committer 2016-08-04 15:26:08 UTC
We should prevent jails from being able to read the kernel message buffer (deny dmesg).  That seems to currently be possible...

root@:/ # sysctl -a | grep jailed
security.jail.jailed: 1
root@:/ # dmesg | wc -l
    1771
root@:/ #
Comment 1 Miroslav Lachman 2016-08-08 10:09:32 UTC
Are you aware of security.bsd.unprivileged_read_msgbuf=0 sysctl?

Do you think we need anything else / jail specific?
Comment 2 Bjoern A. Zeeb freebsd_committer 2016-08-08 11:47:23 UTC
(In reply to Miroslav Lachman from comment #1)

Yes, I mean either have an option to toggle it for jails with a default of "not allowed" or a global if (jailed()) sorry_no();

Should be trivial to implement and not in any critical path, so...
Comment 3 Miroslav Lachman 2016-08-08 12:09:32 UTC
OK, I understand. I can't write a patch, but I am willing to test it :)
Comment 4 Joe Barbish 2016-08-08 13:37:19 UTC
When issuing the dmesg from within a running jail, should issue a error message saying "Error: Command not available from a jail."
Comment 5 Joe Barbish 2016-08-08 15:37:39 UTC
I have been thinking about this more and I remember having this discussion some time a few years ago in the past. There is nothing wrong with the dmesg command issued from within a non-vimage jail showing the in kernel message info. This also happens with the ifconfig command when issued from within a non-vimage jail. 

The intent was not to give a compromised jail attacker any indication he was not on the host, but in a jailed environment. Turning off dmesg or ifconfig when issued from a jail would indeed be such an indication.

In a vnet/vimage this would also be true for the dmesg command.

This is not a bug, but done by design with intent. 

This pr should be closed.
Comment 6 Miroslav Lachman 2016-08-08 16:11:04 UTC
(In reply to Joe Barbish from comment #5)

I don't think so. Attackers can use security.jail.jailed to show the truth.

Leaking SW / HW info from the host to jail by dmesg should be avoided (with configurable sysctl)

We are running all jailers with security.bsd.unprivileged_read_msgbuf=0 for this reason.
Comment 7 Bjoern A. Zeeb freebsd_committer 2016-08-08 21:44:57 UTC
Created attachment 173424 [details]
Patch to allow per-jail msgbuf access

Move the sysctl priv check from the kernel msgbuf sysctl to kern_priv.c.
This not only allows jails to overrule the global decision but also MAC possibly.

The global sysctl to allow unpriv read stays and equally works inside jails (but not per jail).  However jails can entirely disable access now (on by default).


Misses a man page update for allow.read_msgbuf [with allow.noread_msgbuf as counter-option].
Comment 8 Jamie Landeg-Jones 2018-10-11 20:05:42 UTC
This would be useful Any ideas why it never made it?

Cheers
Comment 9 Bjoern A. Zeeb freebsd_committer 2018-10-11 20:14:23 UTC
Jamie (@FreeBSD.org) could you have a look at it.
Should I update it and put it into Phabricator for review?
Would it make sense?
Comment 10 Jamie Gritton freebsd_committer 2018-10-11 21:10:37 UTC
It's just one of those things I  need to get around to that I haven't.  Do you think this is the kind of thing they'd still before the release?

Having given the code a glance, it's certainly straightforward enough.  Adding a permission bit is practically boilerplate, only a touch more complicated for moving the sysctl to a new home.
Comment 11 Bjoern A. Zeeb freebsd_committer 2018-10-11 22:33:04 UTC
(In reply to Jamie Gritton from comment #10)

If you update the patch and have a chance to test it the next few days I think this one can still get in.  I'll be happy to review the updated patch.
Comment 12 dewayne 2018-10-12 00:06:05 UTC
(In reply to Jamie Landeg-Jones from comment #8)
I run a lot of non-vimage jails but I can only see one use-case for this requirement - if I don't/can't access the host system, then a monitoring jail may acquire & provide the dmesg information for a reporting jail?  Is there another use for this, that you have in mind and that we might benefit?

With 
/etc/sysctl.conf:security.bsd.unprivileged_read_msgbuf=0
a jail reports
# dmesg
dmesg: sysctl kern.msgbuf: Operation not permitted
Comment 13 Joe Barbish 2018-10-13 19:13:48 UTC
To keep consistent with how things are done in jail(8) this "security.bsd.unprivileged_read_msgbuf" MIB should be implemented in the same manner as that used for "allow.raw_sockets". The default being not allowed.
This would enable the ability to change the default for all jails or to customize per jail from the jail.conf file. Documented in "man 8 jail".

And while doing this some though should be given to the "security.jail.jailed" MIB. Currently the "sysctl" console command is allowed to be executed from within a non-vnet jail. This leaves the door wide open to a compromised jail being able to obtain information about the host and if he's in a jail. This type of ability is what jail(8) is supposed to stop by design. This hole needs to be plugged. I suggest that the "allow.raw_sockets" method be used to enable the 'sysctl" command to execute from within a jail. The default being not allowed.

The dmesg and sysctl commands provide the same basic info more or less, and since the posters to this PR feel that dmesg is a security leak than for sure sysctl is also.

Even if this change misses the 12.0 deadline, it is a security update and can be added during the life of 12.0.
Comment 14 Jamie Gritton freebsd_committer 2018-10-13 23:13:29 UTC
(In reply to Joe Barbish from comment #13)

You can't just wholesale take away sysctl - there are too many things that use the sysctl interface to have a reasonably functional system when you're through.  For example: you take away your hostname, your processes.  There are individual bits of the MIB that jails shouldn't see, but they're not really the majority and can be handled on a case-by-case basis.

And in particular, there's no point in taking away security.jail.jailed.  It's a boolean in whether you're in a jail, which has such a wide variety of discoverability that you might as well just put it plain in front of your face.  And if you took it away, it would still work, just with ENOENT meaning that you're in a jail.

A jail isn't a virtual machine; it was never an attempt to fool the jailed user into thinking that they're not jailed.  If you care to look, you will know that you're jailed.  You will also know a few different particulars about what your jail can't do, so you can avoid bothering to even try something that doesn't work for your situation.
Comment 15 Jamie Gritton freebsd_committer 2018-10-13 23:17:59 UTC
(In reply to Joe Barbish from comment #13)

> "security.bsd.unprivileged_read_msgbuf" MIB should be implemented in the same manner as that used for "allow.raw_sockets". The default being not allowed.

I'm worried about making allow.read_msgbuf default to not allowed, for the reason that current behavior wouldn't be preserved.  A jail without a particular option should generally behave the same as an older jail when the option didn't exist.  There may be exceptions to this, but I don't see it here.
Comment 16 Jamie Gritton freebsd_committer 2018-10-14 05:56:00 UTC
Created attachment 198114 [details]
Current revision of allow.read_msgbuf patch

I've updated Bjoern's patch for recent changes to allow.* handling, and gave it a mention in jail(8).

As I mentioned, I'm still concerned about this permission bit beingoff by default.  I think I might have misinterpreted Joe's focus (he may have been referring to security.bsd.unprivileged_read_msgbufandnot allow.read_msgbuf), but my comment remains: do we want to change the default behavior, or just allow it to be changed for those who care?

A point in favor of changing the default is this is something of a security issue, so a reasonable default is to tend toward the more secure - plus, that's more  of a reason to include it in 12.  Hmm ... yeah, I can see either side.  So which wins?
Comment 17 Jamie Landeg-Jones 2018-10-14 21:39:50 UTC
(In reply to dewayne from comment #12)

Hi. In my situation, I have a jail where I'd really prefer host information to not leak through as much as possible, but I want it readily available on the host itself for normal users.

I only added a "me too" when I stumbled upon this thread saying it would be relatively easy to add.

As for Joes comment, I hadn't thought about the sysctl leakage, but if I understand correctly, this patch will still stop any user (even root) in the jail from accessing the dmesg portion in sysctl.

As for (the other) Jamie, I can agree with either side, and also disagree with either side, so no help here! :-)
Comment 18 Joe Barbish 2018-10-15 22:34:11 UTC
(In reply to Jamie Gritton from comment #16)

The whole point of this PR is about the ability for the dmesg command to exec from within a jail. The consensus is yes it's a security leak of host information. Now were faced with should "allow.show.dmesg" default to being set to "NO".  As a Jail admin I would prefer additional security to automatically happen without any effort on my part. I think this is such a minor thing that it would go unnoticed.

In this same subject of leaked info into a jail I see 2 additional candidates.

1. The "sysctl" console command. When issued from within a jail it will show the host value. But when you try to use sysctl to change a value you get "Operation not permitted". This is the jail doing it's job. I think a "allow.show.sysctl" should be added with the default being not to show anything.

2. The "kenv" console command. When issued from within a jail it will show the host values. This is giving out info akin to what the dmesg is showing. I think a "allow.show.kenv" should be added with the default being not to show anything.

I see these 3 leaks as trivial items that were over looked in jail(8) original design. Now we have the opportunity to revisit the subject of console commands that leak host info into a jail and close those leaks. 

Their may be other commands that behave in like manner that other people may present here for addressing in the same manner.
Comment 19 Jamie Gritton freebsd_committer 2018-10-16 19:50:50 UTC
(In reply to Joe Barbish from comment #18)

1. The "sysctl" command: the sysctl MIB that the command is an interface to contains a wide variety of things, many of which jails have no need to see, and some of which (e.g. kern.hostname) are considered essential for normal operation, and doubtless some in between.  Many of the jail permission bits are already tied to specific parts of the MIB, but it doesn't make any sense to wholesale turn off the ability to retrieve data via sysctl.  It might make sense to have some kind of jail-readable flag for sysctls, similar to the jail-writable flag that already exists (CTLFLAG_PRISON), but there are many per-value judgement calls to make there.

2. The "kenv" command and associated system call: none of this information looks particularly useful to jails, but neither does it look particularly dangerous.  At first glance, that's a similar situation to dmesg, but the problem with the latter is there's no regulation on the kind of information that might end up in the dmesg buffer.  The kernel environment from kenv isn't so open-ended, and seems to be almost entirely boot/device options.  We may want to hide those, and I doubt that showing them serves anyone any purpose, but I'm not particularly worried about the security implications.
Comment 20 Jamie Gritton freebsd_committer 2018-10-16 19:51:59 UTC
There does seem to be general agreement that the best path is to make the default secure (vs familiar), so I'll ask re@ for go-ahead on the patch.
Comment 21 commit-hook freebsd_committer 2018-10-17 16:12:14 UTC
A commit references this bug:

Author: jamie
Date: Wed Oct 17 16:11:44 UTC 2018
New revision: 339409
URL: https://svnweb.freebsd.org/changeset/base/339409

Log:
  Add a new jail permission, allow.read_msgbuf.  When true, jailed processes
  can see the dmesg buffer (this is the current behavior).  When false (the
  new default), dmesg will be unavailable to jailed users, whether root or
  not.

  The security.bsd.unprivileged_read_msgbuf sysctl still works as before,
  controlling system-wide whether non-root users can see the buffer.

  PR:		211580
  Submitted by:	bz
  Approved by:	re@ (kib@)
  MFC after:	3 days

Changes:
  head/sys/kern/kern_jail.c
  head/sys/kern/kern_priv.c
  head/sys/kern/subr_prf.c
  head/sys/sys/jail.h
  head/usr.sbin/jail/jail.8
Comment 22 commit-hook freebsd_committer 2018-10-20 16:21:11 UTC
A commit references this bug:

Author: jamie
Date: Sat Oct 20 16:20:37 UTC 2018
New revision: 339446
URL: https://svnweb.freebsd.org/changeset/base/339446

Log:
  MFC r339409, r339420:

    Add a new jail permission, allow.read_msgbuf.  When true, jailed processes
    can see the dmesg buffer (this is the current behavior).  When false (the
    new default), dmesg will be unavailable to jailed users, whether root or
    not.

    The security.bsd.unprivileged_read_msgbuf sysctl still works as before,
    controlling system-wide whether non-root users can see the buffer.

  PR:		211580
  Submitted by:	bz

Changes:
_U  stable/11/
  stable/11/sys/kern/kern_jail.c
  stable/11/sys/kern/kern_priv.c
  stable/11/sys/kern/subr_prf.c
  stable/11/sys/sys/jail.h
  stable/11/usr.sbin/jail/jail.8