It might not be :), but surely once people see what the actual administration challenges turn out to be, they/we can write the tools to satisfy those needs? I don't believe they will be insurmountable. You had in the past played with caps quite a bit, do you already have a Ok, here's a patch on top of 2.6.22-rc4-mm2 to do so, thanks, From: Serge E. Hallyn <serue@us.ibm.com> Date: Thu, 21 Jun 2007 11:40:23 -0400 Subject: [PATCH 1/1] file capabilities: make file capabilities option EXPERIMENTAL Make file capabilities depend upon CONFIG_EXPERIMENTAL, as few people have used them to date. Signed-off-by: Serge E. Hallyn <serue@us.ibm.com> --- security/Kconfig | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/security/Kconfig b/security/Kconfig index 7c941d9..ac56c2c 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -81,8 +81,8 @@ config SECURITY_CAPABILITIES If you are unsure how to answer this question, answer Y. config SECURITY_FILE_CAPABILITIES - bool "File POSIX Capabilities" - depends on SECURITY=n || SECURITY_CAPABILITIES!=n + bool "File POSIX Capabilities (EXPERIMENTAL)" + depends on (SECURITY=n || SECURITY_CAPABILITIES!=n) && EXPERIMENTAL default n help This enables filesystem capabilities, allowing you to give -- 1.5.1.1.GIT -
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Serge,
[time passes]
I'm a little better up to speed on all the kernel now. I don't feel that
I conceptually object so much to this patch-series any more.... :-)
I do, however, think the patch needs some work:
1) As previously discussed, fE should be an all or nothing single bit:
How about?:
#define VFS_CAP_REVISION_MASK 0xFF000000
#define VFS_CAP_REVISION 0x01000000
#define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK
#define VFS_CAP_FLAGS_EFFECTIVE 0x000001
struct vfs_cap_data {
__u32 magic_etc;
struct {
__u32 permitted; /* Little endian */
__u32 inheritable; /* Little endian */
} data[1];
};
2) Allocate capability bit-31 for CAP_SETFCAP, and use it to gate
whether the user can set this xattr on a file or not. CAP_SYS_ADMIN is
way too overloaded and this functionality is special.
3) The cap_from_disk() interface checking needs some work.... Most
notably, size must be greater than sizeof(u32) or the very first line
will do something nasty... I'd recommend you use code like this:
[...] cap_from_disk(...)
{
if (size != sizeof(struct vfs_cap_data)) {
printk(KERN_WARNING "%s: invalid cap size %d for file %s\n",
__FUNCTION__, size, bprm->filename);
return -EINVAL;
}
switch ((version & VFS_CAP_REVISION_MASK)) {
case VFS_CAP_REVISION:
bprm->cap_effective = (version & VFS_CAP_FLAGS_EFFECTIVE)
? CAP_FULL_SET : CAP_EMPTY_SET;
bprm->cap_permitted =
to_cap_t( le32_to_cpu(dcap->data[0].permitted) );
bprm->cap_inheritable =
to_cap_t( le32_to_cpu(dcap->data[0].inheritable) );
return 0;
default:
return -EINVAL;
}
}
Basically, I don't believe in designing a secure interface to be forward
compatible - things never work out that way and the legacy you are
implicitly committing to will haunt you in the future... FWIW I've known
a few x86 MSR designers over the years and each one has made this
mistake ...I don't particularly mind, but can you point out any case where it is an advantage to have the one bit for f'E rather than just drop f'E altogether? Instead of having f'I=something f'P=something f'E=off we can always just remove the security.capability xattr. Right? If there's a case where that does not suffice, then I have no objection The functionality is special, but someone with CAP_SYS_ADMIN can always unload the capability module and create the security.capability xattr using the dummy module. If we do add this cap, do we want to make it apply to all security.* Ok, so you're saying that when we do switch to 64-bit caps or some other evolution, we switch to completely separate logic based on the VFS_CAP_REVISION? Sounds sane. If it looks less sane when I try to write the patch I'll Hmm, changing the behavior of the cap_bset is something that seems to belong in 8), though I see what you're saying, it does affect the behavior of vfs caps. One gets a cozy feeling from the fact that cap_bset is set to (~0 & ~~CAP_TO_MASK(CAP_SETPCAP)), but since it's sysctl controllable that seems like it could present a real security problem. So yeah, I think you're right - but the question is whose word do we take here? The admin who set the vfs caps on the binary, or the admin who set cap_bset through sysctl? If you have a list of such cleanups you could send out, we can then decide whether those all are safe to apply to the current capability module, or whether it makes sense to fork off a shiny new capabiltyv2 module :) many thanks for all the suggestions, -
The underlying issue here is the notion of security mechanisms which are built as loadable modules. It's not useful for any in-tree users, and introduces several unnecessary problems which then need to be addressed. A better approach would be to make LSM a statically linked interface. This would also allow us to unexport the LSM symbols and reduce the API abuse by third-party modules. - James -- James Morris <jmorris@namei.org> -
Convert LSM into a static interface, as the ability to unload a security module is not required by in-tree users and potentially complicates the overall security architecture. Needlessly exported LSM symbols have been unexported, to help reduce API abuse. Module parameters for the capability and root_plug modules have been converted to kernel parameters. The SECURITY_FRAMEWORK_VERSION macro has also been removed. Signed-off-by: James Morris <jmorris@namei.org> --- Please review & let me know if anything is broken. Documentation/kernel-parameters.txt | 17 +++++++++++ security/Kconfig | 4 +- security/capability.c | 32 ++++---------------- security/commoncap.c | 3 -- security/dummy.c | 1 - security/root_plug.c | 53 +++++++++++++--------------------- security/security.c | 9 +---- security/selinux/hooks.c | 1 - security/selinux/xfrm.c | 1 - 9 files changed, 48 insertions(+), 73 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 5d0283c..4c406fb 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -74,10 +74,12 @@ parameter is applicable: PPT Parallel port support is enabled. PS2 Appropriate PS/2 support is enabled. RAM RAM disk support is enabled. + ROOTPLUG The example Root Plug LSM is enabled. S390 S390 architecture is enabled. SCSI Appropriate SCSI support is enabled. A lot of drivers has their options described inside of Documentation/scsi/. + SECURITY Different security models are enabled. SELINUX SELinux support is enabled. SERIAL Serial support is enabled. SH SuperH architecture is enabled. @@ -376,6 +378,12 @@ and is between 256 and 4096 characters. It is defined in the file possible to determine what the correct size should be. This option provides an override for these ...
This changes the command line argument. Other than that and a some sanity testing I'll take this. thanks, -chris -
Sigh. So much for my schedule. So, for planning purposes, when ought I expect to have to start dealing with this? Casey Schaufler casey@schaufler-ca.com -
What is your specific concern or use case? -
Just hoping to avoid a change collision. If I have to deal with this today it's easy, if it doesn't show up anywhere until 2.6.28 I'm breezing, but if it all hits in two weeks I have some scrambling and yet another delay to deal with. Not your problem, a little information would be helpful though. BTW, I reviewed my notes from the early days of LSM and it turns out that I agree with the notion that loadable modules don't make a whole lot of sense. So long as I can choose security models as easily as I can change file systems, I'm reasonably happy. That, and that the "default" "regular" policy isn't too terribly different from the traditional Unix policy. Casey Schaufler casey@schaufler-ca.com -
Assuming no issues, 2.6.23 (which is months away, although The default will continue to be capabilities. thanks, -chris -
Good. Thank you again. Casey Schaufler casey@schaufler-ca.com -
I think you will not have too much problem with this patch. After all, you will only need to remove a couple of functions (for the unloading) and take rid of 'old' module parameters (if you use it) -- Roberto De Ioris http://unbit.it JID: roberto@jabber.unbit.it -
Do you mean the name change, or the logic? The name needs to change because kernel parameters are in a global namespace. If the logic has changed, I'm missing something :-) -- James Morris <jmorris@namei.org> -
Sorry, I mean it's currently capability.disable (and the only reason it matters is that at one point I know there were users of it). thanks, -chris -
Convert LSM into a static interface, as the ability to unload a security module is not required by in-tree users and potentially complicates the overall security architecture. Needlessly exported LSM symbols have been unexported, to help reduce API abuse. Parameters for the capability and root_plug modules are now specified at boot. The SECURITY_FRAMEWORK_VERSION macro has also been removed. Signed-off-by: James Morris <jmorris@namei.org> --- Changes: - retain capability.disable kernel param name Documentation/kernel-parameters.txt | 17 +++++++++++ security/Kconfig | 4 +- security/capability.c | 24 ---------------- security/commoncap.c | 3 -- security/dummy.c | 1 - security/root_plug.c | 53 +++++++++++++--------------------- security/security.c | 9 +---- security/selinux/hooks.c | 1 - security/selinux/xfrm.c | 1 - 9 files changed, 41 insertions(+), 72 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 5d0283c..35e1202 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -74,10 +74,12 @@ parameter is applicable: PPT Parallel port support is enabled. PS2 Appropriate PS/2 support is enabled. RAM RAM disk support is enabled. + ROOTPLUG The example Root Plug LSM is enabled. S390 S390 architecture is enabled. SCSI Appropriate SCSI support is enabled. A lot of drivers has their options described inside of Documentation/scsi/. + SECURITY Different security models are enabled. SELINUX SELinux support is enabled. SERIAL Serial support is enabled. SH SuperH architecture is enabled. @@ -376,6 +378,12 @@ and is between 256 and 4096 characters. It is defined in the file possible to determine what the correct size should be. This option provides an override for these situations. ...
is this necessary? What about just documenting
root_plug.{vendor_id,product_id,debug}, so it won't break existing
root_plug users (if there are any) ? I thought that typed
module_param() is prefered over untyped __setup()...
Thanks,
Petr
-
I didn't know module_param was preferred. The idea was that root_plug is example code, and should do the typical thing, which I thought would be __setup. I can easily change it if needed. -- James Morris <jmorris@namei.org> -
I think you want to eliminate that last export too, by taking the security hooks that are called by modules into out-of-line wrapper functions in security.c rather than directly referencing security_ops. -- Stephen Smalley National Security Agency -
Convert LSM into a static interface, as the ability to unload a security module is not required by in-tree users and potentially complicates the overall security architecture. Needlessly exported LSM symbols have been unexported, to help reduce API abuse. Parameters for the capability and root_plug modules are now specified at boot. The SECURITY_FRAMEWORK_VERSION macro has also been removed. Signed-off-by: James Morris <jmorris@namei.org> --- Changes in this version: - retained module params for root_plug - unexorted security_ops, moved inlines to security.c, exported some needed security hooks Please review, I've done quite a bit of testing, but it's a large change now. Documentation/kernel-parameters.txt | 17 + include/linux/security.h | 1171 ++++++----------------------------- security/Kconfig | 4 +- security/capability.c | 24 - security/commoncap.c | 3 - security/dummy.c | 1 - security/root_plug.c | 31 +- security/security.c | 954 ++++++++++++++++++++++++++++- security/selinux/hooks.c | 1 - security/selinux/xfrm.c | 1 - 10 files changed, 1168 insertions(+), 1039 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 5d0283c..cd65510 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -74,10 +74,12 @@ parameter is applicable: PPT Parallel port support is enabled. PS2 Appropriate PS/2 support is enabled. RAM RAM disk support is enabled. + ROOTPLUG The example Root Plug LSM is enabled. S390 S390 architecture is enabled. SCSI Appropriate SCSI support is enabled. A lot of drivers has their options described inside of Documentation/scsi/. + SECURITY Different security models are enabled. SELINUX SELinux support is enabled. SERIAL Serial support is enabled. SH SuperH ...
It's useful for some LSMs to be modular, and LSMs which are y/n options won't have any security architecture issues with unloading at all. The mere fact that SELinux cannot be built as a module is a rather weak argument for disabling LSM modules as a whole, so please don't. Thanks, Andreas -
Which LSMs? Upstream, there are SELinux and capabilty, and they're not That's not the argument. Please review the thread. - James -- James Morris <jmorris@namei.org> -
The argument is 'abuse', right? Abuse is defined as using the LSM hooks for non-security applications, right? It seems to me that the community is doing a good job of discouraging such abuse - by redirecting the "wrong-doers" to implement proper upstream solutions, i.e. taskstats, the audit subsystem, etc. Such encouragement seems a far better response than taking away freedoms and flexibility from everyone. -serge -
We are not living in a world where everyone had good intentions...
For _some_ "wrong-doers" your approach works.
But how do you convince the "wrong-doers" who do things like putting
MODULE_LICENSE("GPL") into their binary-only modules and who ignore you
and get away because noone sues them?
The spirit of the GPLv2 is to defend the freedom of the software
(different from the spirit of the BSD licence), and considering that
there aren't many people defending the GPLv2 copyright of the Linux
kernel at court against abusers, making it harder for people to do the
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
-
Do these really exist? Maybe noone sues them because noone knows who they are... But - note that you've changed completely the meaning of 'abuse'. Well, but you seem to be saying that the license means squat, and resorting to making things inconvenient rather than illegal. Now I guess if it really is accepted that that's the way it should be, then this patch will go in. -serge -
Technical and legal abuse are related.
For GPL'ed modules you might assume good faith and get the authors to do
things in a proper way. Authors of legally questionable modules that
No, the point is that there's no reason for making illegal things
convenient.
I'm not talking about removing things that are used inside the kernel,
but what you call "freedom" can also be called "hooks for possible abuse".
Additionally, it both makes the kernel bigger for everyone and requires
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
-
LinuxAnt? Are they using LSM? True but going by your logic we could remove support for modules period But no, the point is that that you are making legal things very Since capabilities can currently be compiled as a module, you are. thanks, -serge -
The problem is that this would result in distributions having to ship
If the LSM maintainer says non-modular capabilities is the way to go
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
-
Maybe no one knows because the people doing the legal action against them are trying to be nice and do it quietly. And legal action takes time, it is quite slow going unfortunatly. Heck, I've seen code that is even properly licensed under the GPL abuse this security layer for things it was not ment to do at all, and that stuff comes from _very_ big companies that really should know better... So I agree that we should unexport it. It will make people who want to abuse the interface at least think twice about it. thanks, greg "I want to mark structures read-only" k-h -
So they're being nice to the violaters, and then clamping down on But that's back to the other type of 'abuse' which i was originally talking about, and which IMO is being well addressed through education. And I know I'm not the one who's going to stop you... -serge -
Here are a few questions for you: 1) What do you expect to happen to all the megs of security data when you "rmmod selinux"? Do you maintain a massive linked list of security data (with all the locking and performance problems) so that you can iterate over it calling kfree()? What synchronization primitive do we have right now which could safely stop all CPUs outside of security calls while we NULL out and free security data and disable security operations? Don't say "software suspend" and "process freezer", since those have whole order-of-magnitude- complexity problems of their own (and don't always work right either). 2) When you "modprobe my_custom_security_module", how exactly do you expect that all the processes, files, shared memory segments, file descriptors, sockets, SYSV mutexes, packets, etc will get appropriate security pointers? This isn't even solvable the same way the "rmmod" problem is, since most of that isn't even accessible without iterating over the ENTIRE dcache, icache, every process, every process' file-descriptors, every socket, every unix socket, every anonymous socket, every SYSV shm object, every currently-in- process packet. 3) This sounds suspiciously like "The mere fact that the Linux-2.6-VM cannot be built as a module is a rather weak argument for disabling VFS modules as a whole". We don't do "pluggable fundamental infrastructure" in Linux. If it's fundamental infrastructure then you eliminate as many differences as possible and leave the rest to CONFIG options (or delete it entirely). So... Do you have a proposal for solving those rather fundamental design gotchas? If so, I'm sure everybody here would love to see your patch; though maybe not if it's a 32MB patch-zilla-of-doom (AKPM beware, the merge-conflict-from-hell is on its way). On the other hand, if you accept that these problems basically can't be solved and we make things static and rip out a bunch of code, we ...
Oops, typo: Meant to say: "...disabling VM modules as a whole." Cheers, Kyle Moffett -
Read the sentence right above yours again. Those don't all need labels for capabilities, for instance. This No, your argument sounds like "my fs can't be a module so neither should -
Ok, so say we extend LSM to do what AppArmor or TOMOYO need, what do you expect to happen when you "rmmod tomoyo", "rmmod apparmor", or whatever? Each of those is also going to stick lots of context on various objects during the course of running, the same way that the VM subsystem sticks lots of context on filesystem pages while running. Besides, even the standard "capabilities" module wants to attach a list of capabilities to every process and defines Ok, so let's just restrict ourselves to the simple dumb-as-dirt capabilities module. Every process is "labeled" with capabilities while running under that LSM, right? What happens when you "rmmod capabilities"? Do you iterate over all the processes to remove their security data even while they may be using it? Or do you just let it leak? Some daemons test if capabilities are supported, and if so they modify their capability set instead of forking a high-priv and a low-priv process and doing IPC. When you remove the capabilities module, suddenly all those programs will lose that critical "low- privilege" data and become full root. What happens later when you "modprobe capabilities"? Do you suddenly have to stop the system while you iterate over EVERY process to set capabilities based on whether it's root or not? It's also impossible to determine from a given state in time what processes should have capabilities, as the model includes inheritance, which includes processes that don't even Let's go over the differences between "my fs" and "my LSM", and the similarities between "my VM" and "my LSM": Filesystems don't get hooked from virtually every userspace-initiated operation, whereas both VMs and LSMs do. VMs and LSMs attach anonymous state data to a large percentage of the allocated objects in the system, whereas filesystems allocate their own independent datastructure and use that. Would you want to "rmmod ext3" and then "modprobe ext2" while you have an ...
Hmmm. You seem to be mostly concerned with safely rmmod'ing modules. In contrast, my main concern with the proposed patch is that it removes the ability to *insert* a module. Consider the use case of joe admin who is running enterprise-supported RHEL or SLES, and wants to try some newfangled LSM FooSecureMod thingie. So he grabs a machine, config's selinux=0 or apparmor=0 and loads his own module on boot, and plays with it. He even likes FooSecure, better than SELinux or AppArmor, and wants to roll it out across his data center. Without James's patch, he can do that, and at worst has a tainted kernel. RH or Novell or his favorite distro vendor can fix that with a wave of the hand and bless FooSecure as a module. With James's patch, he has to patch his kernels, and then enterprise support is hopeless, to say nothing of the barrier to entry that "patch and rebuild kernel" is more than many admins are willing to do. So to solve the problem James & Kyle are concerned with, and preserve user choice, how about we *only* remove the ability to rmmod, and leave in place the ability to modprobe? Or even easier, LSMs that don't want to be unloaded can just block rmmod, and simple LSMs that can be unloaded safely can permit it. Crispin -- Crispin Cowan, Ph.D. http://crispincowan.com/~crispin/ Director of Software Engineering http://novell.com AppArmor Chat: irc.oftc.net/#apparmor -
I'd argue that security-module-insertion is actually MORE complicated than removal. Here's one example: TOMOYO cares about the process execution tree, but you can't penalize the no-LSM case by a percent or two to add that kind of data. When TOMOYO is loaded, it wants to do access control based on process execution trees for which data DOES NOT EXIST!!! Not only that, but the processes which originally ran the one you care about (and which you'd need to recreate that data) may have exited anywhere from seconds to years before. It is fundamentally IMPOSSIBLE to recreate that data, even if you could solve the problems of how to do it while the system is running without racing with existing process operations. Imagine a process which hasn't had security data tagged to it yet which opens thousands of FIFOs per second, waits for your tagging code to assign security data to them in the filesystem, and then removes them; if you did it right you could prevent the code from EVER completely tagging every object (even assuming you could recreate enough information). Such a need to add extra security data to multiple classes of objects is *fundamental* to any security module (isn't that the whole point?) As such, you can't just "modprobe" one and expect it to work. That's like mounting an ext2 filesystem, and then later trying to "modprobe ext3" and dynamically switch to the ext3 code and enable journalling all at once ON THE MOUNTED FILESYSTEM!!! Sure, theoretically it *could* be done, but the code complexity is hardly worth it (plus nobody has yet even tried posting patches to Flatly impossible. You simply cannot "load" a security module and hope to provide any useful information about the system's present state. If you want comprehensive security it has to be there before a single byte of userspace code is executed. SELinux sort-of handles unlabelled objects by treating them with a small set of initial "types", but ...
there are none, and making the above possible is prohibitively expensive. -
That's not the rationale for the patch, it's just some talking point you picked up. The rationale for the patch is to prevent abuse. So point 1 is 1) Is the LSM infrastructure being abused, and how detrimental is that abuse As has come up, the abuse comes in two forms, and people seem to want to 2) Is the loss of flexibility in the LSM framework a worthwhile tradoff against the abuse prevention. Clearly I and a very few others feel no, and a very vocal set (which sure sounds like a majority) says yes. Now quit trying to give technical justifications for something which is technical only insofar as it is a technical roadblock to prevent a legal LSM is an infrastructure. It's up to the modules to provide that, and it can be done. DTE used to do it. Dirjail used to do it. Capability does it. Another blatant lie, not unlike "come to the table to upstream your LSM, and we'll help you, honest." (The funny thing about that is, I actually like SELinux, more than the alternatives in general. I just can't stand the attitudes voice by much of its camp.) -serge PS - should we rename 'LSM' to 'LSI' - linux security infrastructure? Calling it LSM now is kind of moronic. -
This is not correct. Reducing API abuse is simply a bonus. The rationale for the patch is to remove unneeded infrastructure which complicates security by introducing the idea that the security module can be removed at all. It was in response to your very own posting about the new capabilities code which would need to take this into account. Recall: The underlying issue here is the notion of security mechanisms which are built as loadable modules. It's not useful for any in-tree users, and introduces several unnecessary problems which then need to be addressed. A better approach would be to make LSM a statically linked interface. This would also allow us to unexport the LSM symbols and reduce the API abuse by third-party modules. - James -- James Morris <jmorris@namei.org> -
It's (IMO) by far not the optimal "solution" :) If it is felt a solution is really needed, re-introduction of a security_ops->module_exit hook and introduction of CAP_SYS_CAPDISABLE would be better. But I'm well aware there are far too many (separate and not so separate) agendas driving this, and have no expectations of being able to stop it. James, FWIW, I'm sorry I haven't had a chance to actually test the patch. I'll try to get around to that today or at least this week. -
Patch tests fine for me for expected capability behavior with lsm=n, lsm=y, lsm=y+capability=y, lsm=y+selinux=y, and lsm=y+caps=y+selinux=y. So while I'm opposed to the patch, it appears to be safe. thanks, -serge -
I've also tested a bunch of scenarios: allmodconfig, lsm=y,cap=n, selinux=y,cap=n etc. -- James Morris <jmorris@namei.org> -
I was wondering about the uninlining of all those functions, so did a set of performance runs. Found no statistically relevant change in dbench, tbench, or reaim. (tried to run kernbench too but the benchmark failed somewhere and i didn't care enough to look into it) -serge -
Sigh, as much as I would *like* to stay out of this (I don't use modules at all on any system where I can avoid it), won't it make development - and especially testing - of new lsms much more painful and therefore less likely? I realize there has been a dearth of new LSMs to date, but if for instance a new solaris 10 based capability module were written, well, people would want to be able to rmmod capability modprobe cap_prm thanks, -
The problem is it's not necessarily even safe to do rmmod at all. And modprobe may require extra labelling, or extra checks for unlabelled objects (perhaps not so much for your example). thanks, -chris -
Right, and given that it's trivial for the author of an LSM which shouldn't be modular to make the LSM a boolean config rather than tristate, it doesn't seem like a good reason to take away the ability to have LSM modules. -serge -
While there's lots of pain involved in developing an LSM modern development environments (e.g. virtual machines) I think the value is overrated. You would never want to do that in a production environment, and in a debug environment you could just as easily reboot and get some start-up testing out of the way. Casey Schaufler casey@schaufler-ca.com -
lguest is pretty good for this. You can boot a kernel in approximately the same time as loading a module. -- James Morris <jmorris@namei.org> -
And in a development environment you can just as easily select CONFIG_XYZ=y, no? So we have two options, one which provides greater choice and flexibility. -serge -
I have no problem with leaving things the way they are today, and none with the proposed change. Either way works for me. It would be a little bit better for me if it stayed as is, but that's not a coding issue. Casey Schaufler casey@schaufler-ca.com -
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 No. Bear in mind that capabilities are all about trusting specific applications with privilege as opposed to trusting the superuser to not run dangerous applications. There are three situations, we'll take them in turn: - no capabilities (fP=fI=fE=0): this is for applications that are not intended to operate with privilege. Because of the way the capability convolution rules work, such a program can't execute with privilege. Period. - with capabilities (fP and/or fI != 0), but fE=0 (off): this is for applications that are intended to operate with privilege, but they were designed to know about capabilities and they manipulate (raise and lower) capabilities as needed to do the things they do. - with capabilities, but fE=1 (on): this is a class of applications loosely called 'legacy'. They can use privilege to operate, but don't strictly need to know about it. For example, /bin/chown . Such a program will have fP=0,fI=CAP_CHOWN. Since the administrator sets fP=0,fI=CAP_CHOWN,fE=1 on the /bin/chown file, any process with CAP_CHOWN in its inheritable set (pI) can "exec /bin/chown" and have it do the thing historically reserved for the superuser... In some future world, the legacy fE bit may become unnecessary because every application will be rewritten to be careful about exercising privilege explicitly. In the meantime, the fE bit can be used to drop This argument leads down a rat hole. (As appears to have happened with the non-modularization LSM thread elsewhere...) The simple fact is that CAP_SYS_ADMIN is equivalent to every other capability in the system if it can be used to load any flavor of kernel module. Arguing that you don't need a capability for something because you can do it with CAP_SYS_ADMIN is very close to admitting that you I recommend limiting it to just capabilities. For now, you can leave the other security attributes with the CAP_SYS_ADMIN ("misc") capability. In the original 'POSIX' ...
(Except that in Linux, with SECURE_NOROOT=0, root will be able to. With Yes, thanks, but then it still could come in handy to have fE be a full bitset, so the application gets some eff caps automatically, while Well no, it could also just be acknowledging that at some point some better cap breakup should be attempted, though of course some amount of "these caps can subvert that cap" will always be there. But I'm not actually objecting :) I expect this will be the first of I used to do that (except with a stupid loop), but let's say you update your distro, but the updated kernel has a problem. So you boot into an older kernel. But the distro update added a new capability. Now nothing runs with privilege. Or are you saying that we would name the xattrs 'security.capability.vN', and with each capability we add bump N, so that after we've added 5 capabilities, each binary carries with it 5 Well how about I whip up the patch (when time permits) and see if anyone complains :) thanks, -serge -
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 [We touched on this a number of emails back.] If an application is capability aware, it can manipulate its own capabilities and should have fE=0. If an application is not capability aware, it needs to have *all* of its capabilities enabled at exec() time. Otherwise, it won't work. The only reason for having an fE bitmap is to allow a capability-aware program (you really trust to do its privileged operations carefully) to be lazy and get some of its capabilities raised for free. Perhaps you can clarify why this is a desirable thing? :-) Cheers Andrew -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.6 (GNU/Linux) iD8DBQFGg1LqQheEq9QabfIRAo3BAKCO8QrfcKBNqhfnn2BHp8O/qDkgXgCgleEl xP7LZPU9Qn6AjqI3ZM3FZ+4= =urmz -----END PGP SIGNATURE----- -
Sure - because it doesn't hurt anything, someone just *might* find it useful one day, and mostly the three bitmaps just look a lot cleaner to me than hiding a bit inside the version field. There are a *few* people using this, and so a complete switch in format for no actual net gain seems wrong. If we want to fake fE to the user as being one bit we can do that through the setfcaps/getfcaps programs. There also are prior examples of doing it this way (i.e. Olaf Dietsche's implementation) OTOH I don't deny implementing it fully as you describe seems to make the intent of the code clearer to readers and maintainers. I guess maybe I'll give it a go and see what turns out. thanks, -serge -
The intent of the fE vector in the POSIX draft is that those capabilities are set on exec (lower vectors permitting). There are cases where it No, it's to allow you to grant a subset of the available capabilities to a program that is not aware of capabilities. You can give "date" the capability to reset the clock without giving it the capability to remove other people's files without changing the code or running it setuid. Casey Schaufler casey@schaufler-ca.com -
Would there be a difference between that and setting either fI or fP (depending on your intent) to those caps, and setting fE=1 in Andrew's scheme? thanks, -serge -
Arg, you're making me think. The POSIX group went through this, let me see if I can reconstruct the logic. The main issue is one if there being a possible case where you have a capability ignorant program that you want to exec with a different fP and fE. On first glance it seems that since the program is capability ignorant it can't matter. But what if your capability ignorant program exec's a capability aware program to perform a helper function? You may well want the first program to have a capability that it does not use in fP (but not fE) to pass along to the helper program. True, you could probably come up with a way to set the capabilities on the helper program to account for this use, but there may be design and security constraints that make doing so complicated. Casey Schaufler casey@schaufler-ca.com -
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I'm not sure I've quite flogged this horse to death yet.. :-)
In my other reply, I quoted the rules. Here they are again:
pI' = pI
pP' = (X & fP) | (pI & fI)
pE' = pP' & fE
If program A exec()utes helper program B, then the only capabilities
(p*') that B can get from A are a subset of A's pI set.
If A doesn't know about capabilities, then nothing about the fE value
associated with the A program file can alter A's pI set and thus affect
B. That is, nothing about the fE or fP value used to exec()ute A gets
propagated through a subsequent exec() to B.
So far as I can see, to achieve the helper program support you are
describing, the value of pI that program A (and thus program B) inherits
will have to contain the relevant capabilities, and B will have to have
a sufficient fI value to pick them up...
Incidentally, this is also where my request that we require (pP' >= fP)
be true comes in. If a helper program (which may also be a legacy
program) is used in a way that it is configured (via fP) to have powers
that are denied to it (via X=cap_bset etc.,) then it should simply not
be permitted to run (-EPERM). It should not have the opportunity to
silently confuse itself (as was the case with sendmail when we tried to
I've not seen anything yet to make be believe there is a case for a
non-single bit fE value... Its a little ironic that I read all of the
rationale I've been espousing in POSIX drafts - so far as I'm aware the
only detail I'm mixing in there is the (pP' >= fP), -EPERM, thing.
If you or anyone can cite some counter examples, please do!
Cheers
Andrew
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
iD8DBQFGhJjxQheEq9QabfIRAmyLAKCUxirmAuS4VM0U+9HloeOF6cKt2gCgi/fh
ElhM1CISM4a+e0umBjK9GV0=
=Vrqj
-----END PGP SIGNATURE-----
-
Not really. But, your argument is: fE can only be used to create a different initial pE' than pP'. If the binary doesn't know about capabilities, then you would never want to do that since it won't change it's pE', and therefore it's pP' is meaningless once pE' is set. If the binary does know about capabilities, then it can change it's pE' within the bounds of it's pP' whenever it wants, so we may want to set pE' to 0 at start, but having pE' be just a subset of pP' has no advantage since the binary can set pE' to the subset when it wants. Now, *my* argument :) is that: While there is no particular advantage (that I can think of) to having the bitmap pE', there is also no disadvantage, and it produces kernel code closer to the actual equations usually seen. In the course of this discussion, the two advantages I've seen which I'll concede to you are: 1. the resulting equations may be easier to read/understand, just bc it's one less bitmask operation whose purpose to try to understand. But I'm not certain. 2. Improper setting of fE *could* in theory cause another hard to diagnose sendmail-type vulnerability, by having fP set to the right value, but fE to the wrong value. Though that is stretching things a bit. The change in xattr format offsets those, which is why I like the idea of just having the setfcaps program understand 'on=e' and 'off=e' (where on is of course just an alias for 'all'), but keeping the kernel code the same. -serge -
Nope, I'm fresh out. If the reality is that you get no added value with a vector over a scalar I'm good with either scheme. Looks like you've done the dilegance. I see no flaws in your logic. I suppose I could argue for the vector in terms of compatability with Irix, but I'll leave that to those who might care. Thank you for both the work and the clear explainations. Casey Schaufler casey@schaufler-ca.com -
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This is precisely what fE = 0 or ~0 provides.
Recall, an exec()'d program gets its p*' capabilities from a convolution
of its exec()er's inheritable set (pI) *and* the file's capabilities
(fI,fP,fE):
pI' = pI
pP' = (X & fP) | (pI & fI)
pE' = pP' & fE
[Linux essentially has cap_bset for X.]
The fine-grain ability for ping to do its thing without becoming
powerful enough to load a kernel module, for example, is facilitated by
the "pP' &" part of the derivation of pE' (and not simply the unfiltered
value of fE!).
As I said before, either the program knows how to raise and lower bits
in its pE set, or it doesn't. In the former case, fE=0. In the latter
case, fE=~0 will ensure that it gets all of the capabilities it is
permitted to exercise at time of execution.
Could you cite some examples of where this position is unreasonable?
Thanks
Andrew
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGg9i1+bHCR3gb8jsRAvViAJ9T5x1fHrLGF4niRq7VhRqg4sej3wCgxkom
oAFQEQwLkd/D6J5gi7Fb3Ww=
=+ZLb
-----END PGP SIGNATURE-----
-
All,
Regarding future/backward compatibility of file capabilities:
There are a few obvious approaches we can take:
1. Exactly Andrew describes. Once userspace switches to a new cap
format, an older kernel simply won't support them
2. As Andrew describes, but also encode the version number into the
capability name, i.e. security.capability.v3. Now userspace can
optionally tack on more than one capability version to be backward
compatible.
3. Somewhat different than Andrew describes. We mandate that any
capability version N+1 consist of
struct vfs_cap_data {
__u32 magic;
capability_version_1;
capability_version_2;
...
capability_version_N;
capability_version_N+1;
};
Or, for brevity,
struct vfs_cap_data {
__u32 first_magic;
__u32 last_magic;
capability_version_first;
...
capability_version_last;
};
4. Stick to the current plan, where switching to 64-bit caps will be
done as
struct vfs_cap_data_disk {
__le32 version;
__le32 data[]; /* eff[0], perm[0], inh[0], eff[1], ... */
};
What would people prefer?
thanks,
-serge
-
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 If you have a significant legacy of use of earlier versions, I guess this makes sense. However, given the experimental nature of this support (it will be a while before the user space support for this is Ugh. I don't like this. It presumes that the kernel will get more and While asserting that it is more flexible etc., no one has yet actually given an example of where fE being richer than a simple binary helps anything. Until I see an example, I'm going to hold the position that this is needless "complexity". Cheers Andrew -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGjBFXmwytjiwfWMwRAofJAKCXX2GkN39o45fCQmxpNpZIEVH8EgCeLaDy AoWZNj/1MqT7oayabxUhIn8= =OSBu -----END PGP SIGNATURE----- -
The only counter to this argument is that you now have a different structure on files than on processes. Not a major issue, but one structure to describe capability sets is less complex than two. That way you can have one function to print a capset, regardless of its coming off a file or a process. Just a thought. Casey Schaufler casey@schaufler-ca.com -
