Capabilities are—at least in theory—a nice idea: divide the privileges of root (user ID 0)
into small pieces so that a process can be granted just enough power to perform specific privileged tasks.
If the pieces are small enough, and well chosen, then,
even if a privileged program is compromised (e.g., by a buffer overrun),
the damage that can be done is limited by the set of capabilities that are available to the process.
Good examples of the use of such fine-grained privileges are CAP_KILL,
which permits sending signals to arbitrary processes, and CAP_SYS_TIME,
which permits setting the system clock.
As of Linux 3.2, there are 36 capabilities. You can see a list of
them, along with some of the main powers they each grant, in
the capabilities(7) manual page.
Capabilities can (since Linux 2.6.24) be attached to an executable file,
to create the capabilities equivalent of a set-user-ID-root program: when the executable is run,
the resulting process starts with a limited set of capabilities
(instead of the full power of root, as is the case for set-user-ID-root programs).
The key point from the beginning of this article is small pieces,
and it's here that the Linux capabilities implementation has gone astray.
When a kernel developer adds a new feature that should require privilege,
what capability should they use, or should they perhaps even create a new capability?
Although parceling root privileges into small pieces is useful from a security perspective,
we don't want too many pieces,
since then the task of administering capabilities would become unwieldy.
Thus, it usually makes sense to employ an appropriate existing capability
to control access to a new privileged kernel feature.
And this is where the problem begins. First, there is—unsurprisingly,
given the Linux development model—no central authority determining
how capabilities should be assigned to privileged operations.
Second, there is very little guidance on what capability to choose.
(Probably the best existing guide is to look at the
capabilities(7) man page.
By comparing with existing uses in that page,
we can get some guidance on choosing the capability that best matches a new use case.)
So in practice, what happens?
A kernel developer looks at the list of available capabilities in the kernel
include/linux/capability.h header file,
and is likely left bewildered wondering which capability to choose.
(It appears that the original intent was that this header file
would be updated with comments for all of the usages of each
capability, so as to give an overview of capability usage,
but in practice those comments have been updated only sporadically.)
But the developer does know one thing: their feature will likely be administered by system administrators,
and, helpfully, there is a capability called CAP_SYS_ADMIN.
So, lacking sufficient information for a decision,
the developer chooses CAP_SYS_ADMIN for their new feature.
Which brings us to where we are today:
of the 1167 uses of capabilities in C files in the Linux 3.2 source code,
451 of those uses are CAP_SYS_ADMIN.
That's rather more than a third of all capability checks.
We might wonder if CAP_SYS_ADMIN is overrepresented because of
duplications of similar operations in the kernel arch/ trees,
or because CAP_SYS_ADMIN is commonly assigned as the
capability governing administrative functions on device drivers.
However, even after eliminating drivers/ and architectures other than x86,
CAP_SYS_ADMIN still accounts for 167—about 30%—of the 552 uses of capabilities.
(Fuller details about usage of capabilities in current and earlier kernels can be found
here.)
So, on the one hand, the powers granted by CAP_SYS_ADMIN are so numerous and wide ranging that,
armed with that capability,
there are several avenues of attack by which a rogue process could gain all of the other capabilities.
(As has been summarized by Brad Spengler,
the ability to be leveraged for full root privileges is a
weakness of many existing capabilities;
CAP_SYS_ADMIN is just the most egregious example.)
On the other hand, so many privileged operations require CAP_SYS_ADMIN
that it is the capability most likely to be assigned to a privileged program.
To summarize: CAP_SYS_ADMIN has become the new root.
If the goal of capabilities is to limit the power of privileged programs to be less than root,
then once we give a program CAP_SYS_ADMIN the game is more or less
over. That is the manifest problem revealed from the above analysis.
However, if we look further, there is evidence of an additional problem,
one that lies in the Linux development model.
As noted above, if we eliminate drivers/ and architectures other than x86,
CAP_SYS_ADMIN accounts for 30% of the uses of capabilities.
However, when capabilities were first introduced in Linux 2.2,
the corresponding figures were 23 of 147 uses (16%).
This supports a hypothesis that when random kernel developers are faced with the question
"What capability should I use to govern access to the privileged feature that I'm adding to the kernel?",
the answer often goes "I'm not sure… maybe CAP_SYS_ADMIN?".
In other words, the Linux kernel development model
(where, for example, there is no overall coordination of the use of capabilities)
appears not to scale well when multiple developers face questions of this sort.
(In retrospect, it also seems clear that the choice
of the name CAP_SYS_ADMIN was rather unfortunate.
The name conveys no real information about what operations the capability should govern,
and it's an easy choice that looks safe to kernel developers
who are uncertain of what capability to use.)
What could be done to improve matters?
There's no quick and easy way out of the existing situation,
but there are some steps that could be taken:
- Avoid new kinds of uses of CAP_SYS_ADMIN.
(As this article was being written, Linux 3.3-rc is adding 13 new uses of capabilities.
Most of them are CAP_SYS_ADMIN,
and at least some of them may be new kinds of uses of that capability. One
such use has been averted, however.)
- Rename CAP_SYS_ADMIN to CAP_AS_GOOD_AS_ROOT.
Well, maybe not.
But such a change would help get the point across to kernel developers
looking to choose a capability for their new feature.
- Publish better guidelines on the use of capabilities.
Past attempts to do this (the capabilities(7) man page
and comments in include/linux/capability.h)
have only had limited success
(the guidelines are incomplete, and haven't done much to alleviate the problem).
However, some more explicit guidelines,
coupled with some measurements of the kernel source (see next point),
might achieve better results.
- Regularly publish statistics on the use of capabilities in the
kernel source and monitor new uses of capabilities in each kernel release
(e.g., employ some scripting to look at capability-related changes in the
diff for the current -rc release).
- Existing uses of CAP_SYS_ADMIN could be divided out into other existing capabilities,
and possibly some new capabilities.
Those capabilities could then be assigned to privileged programs instead of CAP_SYS_ADMIN.
(For application backward-compatibility,
the kernel capability checks wouldn't remove CAP_SYS_ADMIN,
but rather would check for CAP_SYS_ADMIN or its replacement.
This would allow old binaries that have the CAP_SYS_ADMIN capability to continue to work,
while new binaries would be assigned the replacement capability.)
One or two steps in this direction have already been made, for example, with
the addition of the CAP_SYSLOG capability
in Linux 2.6.37.
An obvious first point of focus would be non-generic uses of CAP_SYS_ADMIN
in areas other than drivers and the file-system trees.
Next points of focus could be generic uses of CAP_SYS_ADMIN
in the drivers/ and fs/ trees.
- Do a similar analysis of other heavily used capabilities,
especially CAP_NET_ADMIN,
to see whether splitting would be useful for those capabilities.
(CAP_NET_ADMIN has 395 uses in Linux 3.2.
However, all of those uses are restricted to code in the
drivers/net/ and net/ subdirectories.
If we remove CAP_NET_ADMIN from the discussion,
then there are more uses of CAP_SYS_ADMIN in the
kernel source than all of the remaining capabilities combined.)
As well as the above, of course the problem outlined by Brad Spengler
that many capabilities can be leveraged to gain full root access remains to be addressed.
(Ongoing work on namespaces will help improve this situation
for some capabilities when used in conjunction with containers.)
In summary, capabilities go some way toward improving application security,
but there's still further work needed before they can deliver
on their early promise of being a mechanism for providing
discrete, non-elevatable privileges to applications.
Furthermore, as the example of the ever-widening scope of CAP_SYS_ADMIN shows,
some questions requiring coordinated answers
are currently not well addressed by the distributed Linux development model.
[Acknowledgment: Thanks to Serge Hallyn
for comments on an early draft of this article.]
Comments (45 posted)
Brief items
This led us to ask, if in the worst case users chose multi-word passphrases
with a distribution identical to English speech, how secure would this be?
Using the large Google n-gram corpus we can answer this question for
phrases of up to 5 words. The results are discouraging: by our metrics,
even 5-word phrases would be highly insecure against offline attacks, with
fewer than 30 bits of work compromising over half of users. The returns
appear to rapidly diminish as more words are required. This has potentially
serious implications for applications like PGP private keys, which are
often encrypted using a passphrase.
--
Joseph Bonneau
Within 48 hours of the system going live, we had gained near-complete control of the election server. We successfully changed every vote
and revealed almost every secret ballot. Election officials did not detect
our intrusion for nearly two business days — and might have remained
unaware for far longer had we not deliberately left a prominent clue.
--
Scott
Wolchok, Eric Wustrow, Dawn Isabel, and J. Alex Halderman in
Attacking the Washington, D.C.
Internet Voting System [PDF]
Comments (20 posted)
New vulnerabilities
flash-player: multiple vulnerabilities
| Package(s): | flash-player |
CVE #(s): | CVE-2012-0768
CVE-2012-0769
|
| Created: | March 8, 2012 |
Updated: | March 14, 2012 |
| Description: |
From the CVE entries:
The Matrix3D component in Adobe Flash Player before 10.3.183.16 and 11.x before 11.1.102.63 on Windows, Mac OS X, Linux, and Solaris; before 11.1.111.7 on Android 2.x and 3.x; and before 11.1.115.7 on Android 4.x allows attackers to execute arbitrary code or cause a denial of service (memory corruption) via unspecified vectors. (CVE-2012-0768)
Adobe Flash Player before 10.3.183.16 and 11.x before 11.1.102.63 on Windows, Mac OS X, Linux, and Solaris; before 11.1.111.7 on Android 2.x and 3.x; and before 11.1.115.7 on Android 4.x does not properly handle integers, which allows attackers to obtain sensitive information via unspecified vectors. (CVE-2012-0769) |
| Alerts: |
|
Comments (none posted)
freetype: code execution
| Package(s): | freetype |
CVE #(s): | CVE-2012-1133
CVE-2012-1134
CVE-2012-1136
CVE-2012-1142
CVE-2012-1144
|
| Created: | March 9, 2012 |
Updated: | March 23, 2012 |
| Description: |
From the Debian advisory:
Mateusz Jurczyk from the Google Security Team discovered several
vulnerabilties in Freetype's parsing of BDF, Type1 and TrueType fonts,
which could result in the execution of arbitrary code if a malformed
font file is processed. |
| Alerts: |
|
Comments (none posted)
gdm-guest-session: arbitrary file deletion
| Package(s): | gdm-guest-session |
CVE #(s): | CVE-2012-0943
|
| Created: | March 13, 2012 |
Updated: | March 14, 2012 |
| Description: |
From the Ubuntu advisory:
Ryan Lortie discovered that gdm-guest-session improperly cleaned out
certain guest session files. A local attacker could use this issue to
delete arbitrary files. |
| Alerts: |
|
Comments (none posted)
glibc: multiple vulnerabilities
| Package(s): | eglibc, glibc |
CVE #(s): | CVE-2011-1658
CVE-2011-2702
|
| Created: | March 12, 2012 |
Updated: | March 14, 2012 |
| Description: |
From the Ubuntu advisory:
It was discovered that the GNU C library loader expanded the
$ORIGIN dynamic string token when RPATH is composed entirely of this
token. This could allow an attacker to gain privilege via a setuid
program that had this RPATH value. (CVE-2011-1658)
It was discovered that the GNU C library implementation of memcpy
optimized for Supplemental Streaming SIMD Extensions 3 (SSSE3)
contained a possible integer overflow. An attacker could use this to
cause a denial of service or possibly execute arbitrary code. This
issue only affected Ubuntu 10.04 LTS. (CVE-2011-2702) |
| Alerts: |
|
Comments (none posted)
gnutls: information disclosure
| Package(s): | gnutls |
CVE #(s): | CVE-2012-0390
|
| Created: | March 9, 2012 |
Updated: | August 7, 2012 |
| Description: |
From the CVE entry:
The DTLS implementation in GnuTLS 3.0.10 and earlier executes certain error-handling code only if there is a specific relationship between a padding length and the ciphertext size, which makes it easier for remote attackers to recover partial plaintext via a timing side-channel attack, a related issue to CVE-2011-4108.
|
| Alerts: |
|
Comments (none posted)
icecast: forged log entries
| Package(s): | icecast |
CVE #(s): | CVE-2011-4612
|
| Created: | March 8, 2012 |
Updated: | October 24, 2012 |
| Description: |
From the openSUSE advisory:
Icecast didn't strip newlines from log entries, therefore allowing users to forge log entries. |
| Alerts: |
|
Comments (none posted)
kernel: null pointer reference on readonly regsets
| Package(s): | kernel |
CVE #(s): | CVE-2012-1097
|
| Created: | March 12, 2012 |
Updated: | November 5, 2012 |
| Description: |
From the Red Hat bugzilla:
The regset common infrastructure assumed that regsets would always have .get and .set methods, but not necessarily .active methods. Unfortunately people have since written regsets without .set methods.
Rather than putting in stub functions everywhere, handle regsets with null .get or .set methods explicitly. |
| Alerts: |
|
Comments (none posted)
ldm: command execution as root
| Package(s): | ldm |
CVE #(s): | CVE-2012-1166
|
| Created: | March 13, 2012 |
Updated: | March 14, 2012 |
| Description: |
From the Ubuntu advisory:
Tenho Tuhkala discovered that the LTSP Display Manager (ldm) incorrectly
filtered keybindings. An attacker could use the default keybindings to
execute arbitrary commands as root at the login screen.
|
| Alerts: |
|
Comments (none posted)
libdbd-pg-perl: format string vulnerabilities
| Package(s): | libdbd-pg-perl |
CVE #(s): | CVE-2012-1151
|
| Created: | March 12, 2012 |
Updated: | August 2, 2012 |
| Description: |
From the Debian advisory:
Niko Tyni discovered two format string vulnerabilities in DBD::Pg, a Perl
DBI driver for the PostgreSQL database server, which can be exploited
by a rogue database server. |
| Alerts: |
|
Comments (none posted)
libyaml-libyaml-perl: format string vulnerabilities
| Package(s): | libyaml-libyaml-perl |
CVE #(s): | CVE-2012-1152
|
| Created: | March 13, 2012 |
Updated: | August 17, 2012 |
| Description: |
From the Debian advisory:
Dominic Hargreaves and Niko Tyni discovered two format string
vulnerabilities in YAML::LibYAML, a Perl interface to the libyaml
library. |
| Alerts: |
|
Comments (none posted)
lightdm: arbitrary file deletion
| Package(s): | lightdm |
CVE #(s): | CVE-2012-1111
|
| Created: | March 13, 2012 |
Updated: | March 14, 2012 |
| Description: |
lightdm previous to version 1.0.9 allows file descriptors to leak into the session processes. |
| Alerts: |
|
Comments (none posted)
Mozilla products: multiple vulnerabilities
| Package(s): | firefox thunderbird seamonkey |
CVE #(s): | CVE-2012-0451
CVE-2012-0455
CVE-2012-0456
CVE-2012-0457
CVE-2012-0458
CVE-2012-0459
CVE-2012-0460
CVE-2012-0461
CVE-2012-0462
CVE-2012-0464
|
| Created: | March 14, 2012 |
Updated: | July 23, 2012 |
| Description: |
The Red Hat advisory nicely describes the latest round of Mozilla vulnerabilities, most of which are fixed in the Firefox 11 and Thunderbird 11 releases:
Several flaws were found in the processing of malformed web content. A web
page containing malicious content could cause Firefox to crash or,
potentially, execute arbitrary code with the privileges of the user
running Firefox. (CVE-2012-0461, CVE-2012-0462, CVE-2012-0464)
Two flaws were found in the way Firefox parsed certain Scalable Vector
Graphics (SVG) image files. A web page containing a malicious SVG image
file could cause an information leak, or cause Firefox to crash or,
potentially, execute arbitrary code with the privileges of the user running
Firefox. (CVE-2012-0456, CVE-2012-0457)
A flaw could allow a malicious site to bypass intended restrictions,
possibly leading to a cross-site scripting (XSS) attack if a user were
tricked into dropping a "javascript:" link onto a frame. (CVE-2012-0455)
It was found that the home page could be set to a "javascript:" link. If a
user were tricked into setting such a home page by dragging a link to the
home button, it could cause Firefox to repeatedly crash, eventually
leading to arbitrary code execution with the privileges of the user
running Firefox. (CVE-2012-0458)
A flaw was found in the way Firefox parsed certain web content containing
"cssText". A web page containing malicious content could cause Firefox to
crash or, potentially, execute arbitrary code with the privileges of the
user running Firefox. (CVE-2012-0459)
It was found that by using the DOM fullscreen API, untrusted content could
bypass the mozRequestFullscreen security protections. A web page containing
malicious web content could exploit this API flaw to cause user interface
spoofing. (CVE-2012-0460)
A flaw was found in the way Firefox handled pages with multiple Content
Security Policy (CSP) headers. This could lead to a cross-site scripting
attack if used in conjunction with a website that has a header injection
flaw. (CVE-2012-0451)
|
| Alerts: |
|
Comments (none posted)
python-pam: code execution
| Package(s): | python-pam |
CVE #(s): | CVE-2012-1502
|
| Created: | March 8, 2012 |
Updated: | April 12, 2012 |
| Description: |
From the Ubuntu advisory:
Markus Vervier discovered that PyPAM incorrectly handled passwords
containing NULL bytes. An attacker could exploit this to cause applications
using PyPAM to crash, or possibly execute arbitrary code. |
| Alerts: |
|
Comments (none posted)
tremulous: code execution
| Package(s): | tremulous |
CVE #(s): | CVE-2011-3012
|
| Created: | March 8, 2012 |
Updated: | March 14, 2012 |
| Description: |
From the CVE entry:
The ioQuake3 engine, as used in World of Padman 1.2 and earlier, Tremulous 1.1.0, and ioUrbanTerror 2007-12-20, does not check for dangerous file extensions before writing to the quake3 directory, which allows remote attackers to execute arbitrary code via a crafted third-party addon that creates a Trojan horse DLL file, a different vulnerability than CVE-2011-2764. |
| Alerts: |
|
Comments (none posted)
Page editor: Jake Edge
Next page: Kernel development>>