Summary: | deny system message buffer access from jails | ||||||||
---|---|---|---|---|---|---|---|---|---|
Product: | Base System | Reporter: | Bjoern A. Zeeb <bz> | ||||||
Component: | kern | Assignee: | freebsd-jail (Nobody) <jail> | ||||||
Status: | Closed FIXED | ||||||||
Severity: | Affects Some People | CC: | 000.fbsd, bz, dewayne, jamie, jamie, pi, qjail1, swills | ||||||
Priority: | --- | Keywords: | patch, security | ||||||
Version: | CURRENT | ||||||||
Hardware: | Any | ||||||||
OS: | Any | ||||||||
Attachments: |
|
Description
Bjoern A. Zeeb
2016-08-04 15:26:08 UTC
Are you aware of security.bsd.unprivileged_read_msgbuf=0 sysctl? Do you think we need anything else / jail specific? (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... OK, I understand. I can't write a patch, but I am willing to test it :) When issuing the dmesg from within a running jail, should issue a error message saying "Error: Command not available from a jail." 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. (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. 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].
This would be useful Any ideas why it never made it? Cheers 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? 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. (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. (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 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. (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. (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. 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?
(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! :-) (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. (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. 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. 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 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 |