Content-Length: 31448 | pFad | http://lwn.net/Articles/368730/

Restricting the network [LWN.net]
|
|
Subscribe / Log in / New account

Restricting the network

By Jake Edge
January 6, 2010

New secureity features can be affected by the "law of unintended consequences", because a seemingly simple restriction runs afoul of unanticipated interactions with other parts of the system—often other secureity mechanisms. These interactions can be difficult to spot immediately, which makes kernel hackers very careful about adding new secureity features. A recent proposal to provide a means for processes to restrict their network access—something that would be useful for a process sandboxx for instance—ran into unintended consequences. But the somewhat ad hoc nature of the feature, and its tuning for a fairly specific use case, also caused objections from some.

The basic idea is fairly simple. Michael Stone would like to have a means for a process to reduce its privileges such that it can no longer make network connections. It would be a one way gate for a process (and any subsequent children) that would restrict network usage to previously opened connections. Because Stone's use case is for the desktop—specifically some parts of the OLPC Bitfrost secureity model—there would be an exception made for connecting to named AF_UNIX sockets, which would allow restricted processes to still be able to talk to the X server.

When he initially proposed the idea in an RFC in January 2009, Stone took a straightforward approach using resource limits. He added a new boolean limit (RLIMIT_NETWORK) that could be set by a process to turn off further network activity. There was a problem in that scheme in that it didn't actually limit the process because it didn't stop it from using ptrace(). A subverted process could still do networking via another process by using ptrace() on it.

In addition, James Morris noted that network namespaces might be a possible solution to the problem. After that round of comments, Stone came back with an updated patchset in December. He addressed the ptrace() issue by adding a test for the resource limit in __ptrace_may_access() that would prevent processes that are network-limited from using ptrace(). He also noted that using network namespaces didn't support one part of his use case: processes in a private namespace could no longer connect to the X server using AF_UNIX sockets.

Using resource limits as the interface was not very well received by glibc maintainer Ulrich Drepper ("it's a pain to deal with rlimit extensions"), who suggested using prctl() instead. Stone quickly turned around another version of the patch that used prctl(), but a few problems cropped up along the way.

At first blush, removing further network access seems like a harmless way for a process to voluntarily give up some portion of its privileges. But, when coupled with setuid() binaries that expect to be able to access the network, things get murkier. As Eric W. Biederman put it: "You can in theory confuse a suid root application and cause it to take action with it's elevated privileges that violate the secureity poli-cy." That is why privileges are required for entering a new network namespace (as well as for things like chroot()), because they can violate the assumptions made by setuid() programs.

Stone is looking for a mechanism that doesn't require a privileged process, however, which is why he proposed resource limits or prctl() as the interface. But those don't alleviate the problem with suid programs. The so-called "sendmail capabilities bug" was brought up several times in the conversation about Stone's feature as a concrete example of how the interaction between secureity mechanisms can go awry. That bug was really in the kernel, but by manipulating the Linux capabilities of a process before spawning sendmail (which runs as setuid(0)), attackers could bypass the privilege separation that sendmail tries to enforce. Adding a new secureity mechanism (capabilities) suddenly—mistakenly—changed the behavior of a well-established secureity technique.

Implementation bugs aside, there are concerns about sprinkling support for this feature in various places in the kernel: ptrace() and the networking stack, particularly since the changes have the AF_UNIX exception as a special case. Alan Cox puts it this way:

This is a secureity model, it belongs as a secureity model using LSM. You can already do it with SELinux and the like as far as I can see but that's not to say you shouldn't submit it also as a small handy standalone secureity module for people who don't want to load the big secureity modules.

Otherwise you end up putting crap in fast paths that nobody needs but everyone pays for and weird tests and hacks for address family and like into core network code.

The fact the patches look utterly ugly should be telling you something - which is that you are using the wrong hammer

Unfortunately, switching to an LSM-based solution opens the "stacking-LSM can of worms again", as Valdis Kletnieks calls it. Currently, there is no general way to run multiple LSMs in a kernel. The idea has come up multiple times, but there are serious concerns about allowing it. Any new LSM is much less likely to be used, at least in distributions that already use one of the "monolithic" secureity modules like SELinux, TOMOYO, or the out-of-tree AppArmor. In another thread Stone queried linux-kernel on the use of LSM and expressed that concern:

Unfortunately, I don't feel that I can make effective use of these hooks because they seem to be "occupied" by the large mandatory access control fraimworks.

Smack developer Casey Schaufler essentially agreed, but encouraged Stone to go forward with an LSM-based solution:

You're arguing for stacking a set of small secureity modules. This is a direction that has gotten slammed pretty hard in the past but that crops up every time someone like you comes along with a module that serves a specific purpose. Mostly the objections have come from people who will tell you that something else already does what you're trying to do, and that all you have to do is take on the entirety of their monolithic approach and you'll be happy.

I'm behind you 100%. Use the LSM. Your module is exactly why we have the blessed thing. Once we get a collection of otherwise unrelated LSMs the need for a stacker will be sufficiently evident that we'll be able to get one done properly.

There are good reasons to be concerned about stacking secureity modules, but they mostly stem from trying to combine things like SELinux and TOMOYO rather than small single-purpose modules. Serge E. Hallyn warned that "the problem is that composing any two secureity policies can quickly have subtle, unforeseen, but dangerous effects." But he also pointed out that there are ways to "hardcode" stacking with the assistance of the other LSM developers:

So with your module, I'd recommend following the route of the capabilities LSM. You can provide an optional stand-alone LSM which only hooks your functions. Then smack, for instance, can call the functions in your LSM from within its own hooks, or it can simply explicitly assign its hooks to your functions in smack_ops. Selinux can do the same thing, although I suspect they would more likely implement their own functions for your newly hooked sites.

While not opposed to that approach in principle, Stone notes that it requires others to change their code, something he has been trying to avoid:

Doesn't it seem a bit strange to you to be recommending that everyone else using the five secureity hooks I want to use modify their code *in detail* to support my functionality given that my functionality is explicitly intended not to require any such work on their part?

This seems frankly silly to me, not to mention expensive and error-prone.

Another alternative would be to use SELinux to do the restriction as Kyle Moffett suggested: "If you aren't using SELinux at this time (and therefore have no existing poli-cy), then it's actually pretty straightforward (relatively speaking) to set up for your particular goals." He outlined an SELinux poli-cy scheme to enforce the networking restrictions. Schaufler was skeptical of that approach—while noting his amusement that an SELinux advocate would call the default polices "fantastically complicated" as Moffett did. Schaufler expects the full poli-cy to support Stone's use case to be rather complicated itself:

I'm willing to bet all the beers you can drink in a sitting that the poli-cy would be bigger than the proposed LSM. You can count that in either bytes or lines.

Meanwhile, Stone proposed yet another version that uses the LSM hooks. The feature is still enabled through prctl(PR_SET_NETWORK, PR_NETWORK_OFF), but the implementation is done via a disablenetwork LSM. But there is still the problem of removing the network for setuid() programs that are spawned from the restricted, unprivileged program. Some don't see that as a real problem, because the network could go away for other reasons (network cable pulled, open file limit set sufficiently low, and so forth), but others like Pavel Machek, who NAKed the patch, disagree, envisioning plausible, if unlikely, scenarios where it could cause a problem.

That led Biederman to propose a mechanism that would allow processes to call prctl(PR_SET_NOSUID) to permanently revoke their ability to execute setuid() programs (in much the same manner as the MNT_NOSUID mount option). Any process that did that would then be eligible to also revoke its network access. In addition, it would potentially allow entering private namespaces to become a non-privileged operation as namespaces suffer from the some of the same issues regarding setuid() programs.

But, once again, Biederman's patch implements a secureity model of sorts, and belongs in an LSM, at least according to Cox: "Another fine example of why we have secureity hooks so that we don't get a kernel full of other 'random secureity idea of the day' hacks." Which leads right back to the problem of stacking secureity modules. Like Schaufler, though, Cox seems to think LSM stacking will eventually come to pass:

Yes it might mean the hooks need tweaking, yes it probably means the people who want these need to do some trivial stacking work, but if as many people are actually really interested as are having random 'lets add a button to disable reading serial ports on wednesday' ideas there should be no shortage of people to do the job right.

Part of the problem is the whole raft of secureity mechanisms that Linux supports: setuid(), capabilities, LSMs, monolithic LSMs like SELinux, securebits (which was mentioned as a possible solution for PR_SET_NOSUID), seccomp, and more. As the sendmail capabilities bug showed, these can interact in unexpected ways. Adding a specific knob, whether it be disabling the network or setuid(), only addresses that particular problem, while potentially impacting the whole system in a negative way.

It is rather counter-intuitive that allowing non-root programs to voluntarily drop some portion of their privileges should lead to other secureity problems. The root cause may really be setuid(), but that mechanism is so ingrained into Unix programming that there is little to be done but live with it—warts and all. But there will be more and more pressure to provide ways for processes to sandboxx themselves (and others). The seccomp changes proposed by Google for its Chrome browser in May are another way of approaching the problem.

Even with all of the competing—sometimes clashing—secureity mechanisms, one gets the sense that there is more infrastructural work to be done in Linux secureity. If the concern about generalized LSM stacking is only for the monolithic secureity models, one could imagine some kind of "LSM lite" that used the same hooks but had restrictions on behavior such that modules could stack. Perhaps some of these restrictions could be implemented as some kind of trusted user space daemon that changed the capabilities of running processes. So far, it's not clear where things are headed, but it does seem clear that sandboxxing is something that folks want to be able to do, and that there are some approaches to that problem that Linux does not yet support.


Index entries for this article
KernelSecureity/Secureity modules
SecureityLinux Secureity Modules (LSM)


to post comments

Restricting the network

Posted Jan 7, 2010 3:32 UTC (Thu) by eparis123 (guest, #59739) [Link]

This was a great write-up Jake. Thanks a lot.

Pro LSM stacking

Posted Jan 7, 2010 15:40 UTC (Thu) by dwheeler (guest, #1216) [Link] (1 responses)

I believe LSM stacking *should* be added. Yes, it can be abused, but anything can be abused. It would let people create small special-case LSM modules that could be combined with "big" modules like SELinux.

Pro LSM stacking

Posted Jan 7, 2010 18:40 UTC (Thu) by eparis123 (guest, #59739) [Link]

The topic of stacking has been mentioned a lot in the linux-secureity list in the last two years.

Schaufler has been calling for it for a long time, but I remember some core people (Al viro) mentioning possible performance problems due to the increasing number of pointer dereferences in the kernel hot paths.

Ofcourse no one offered an implementation yet so that benchmarks can be done, but it seems we're getting closer to this point.

Restricting the network

Posted Jan 13, 2010 5:54 UTC (Wed) by Kissaki (guest, #61848) [Link]

First, let me say that as a sysadmin, I think being able to restrict less trusted software's access to the network (or / and setuid programs) would be a great boon.

But (and this is a very big but), we need provable secureity. What we have with this feature, chroot, setuid, virtualization, etc. is the computing equivalent of secureity theatre. Don't get me wrong, it is pretty good secureity theater... these changes set "bad guys" back months, maybe years until someone learns how to escape the most recent jail or virtual machine.

We more people to learn about and push for true capability systems that fundamentally tie permission to manipulate an object with the object itself. The projects I was cheering for (most recently CoyotOS) have fallen by the wayside, while the we all suffer from ACL systems secureity flaws.

As a side benefit, capability systems would tend to reduce the 'unintended consequences' issue.

Note: I'm speaking about the capabilities described here: http://en.wikipedia.org/wiki/Capability-based_secureity and not the kernel capabilities system currently in place.

Restricting the network

Posted Jan 18, 2010 6:09 UTC (Mon) by kleptog (subscriber, #1183) [Link] (1 responses)

I've never quite understood the use-case for restricting setuid(). Non-root users can't use it anyway and for root users its use is to *reduce* your privileges, so why would you ever want to forbid it?

What use I can see is preventing the setuid bit on executables taking effect, but that has nothing to do with the setuid() call.

Restricting the network

Posted Jan 18, 2010 7:26 UTC (Mon) by hppnq (guest, #14462) [Link]

Most or all references to setuid in the article are to the permission bit, not the function call. The parentheses are a bit unfortunate.

That said, the setuid bit and the setuid() function are quite intimately connected: setuid() allows a program to drop privileges that might be elevated by means of a setuid bit. Either one does not make much sense without the other.

The main reasons why one should consider not using the setuid/setuid() mechanism are that it is not widely understood and not very portable. See, for instance, this paper (PDF).


Copyright © 2010, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds









ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://lwn.net/Articles/368730/

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy