Sorry for this quite long email, but I have tried to summarise
my ideas after reading about the capabilities in Kernel Traffic #59.
Unfortunately I am not reading either the kernel-list regularly,
so there must be some (or a lot?) of sentence, which is already
covered by previous emails. Please Cc: me <Akos.Frohner@elte.hu>
your answer, because of this reason!
To be short: I would associate capabilities to users not to files.
New idea: capabilities for code segments.
Problems:
---------
putpwent
An average user should be able to set her/his password.
It requires special privileges to write to the central
database.
daemon
A daemon process needs special privileges to complete
certain tasks (e.g. open a port under 1024), but only
root is allowed to do this.
In both cases the root account has too many unnecessary
capabilities or privileges, thus a broken program may cause
unpredictable events.
We shall be able to describe fine details of these capabilities.
The questions are:
- Where shall we put the descriptions?
- Shall we associate these descriptions with users or files?
- How fine details are described?
Capability like things in other systems:
----------------------------------------
VMS
Priv - a token, which allows certain system calls.
Privs are normally associated to users, not to files.
There is no notion of root, but a user with all
privs set may act like this.
The problem of "putpwent" is solved by installed
images, where the image receives the privs during
the installation into the memory (e.g. at boot).
[My interpratation to UNIX like systems: the program
is running like a daemon under root userid and a
user may call a function of this program ... like
a client-server scheme without explicit protocol.]
The installed image has to throw away the privs,
when it is calling a code outside.
NT
VMS like priv system, with no notion of root.
Privs are associated to users, not to files.
One may run services (daemon processes) under
certain user accounts. There is no notion of root.
AFAIK the problem of "putpwent" is solved by a
system call.
AIX 4.x
Role - a token, which will pass certain security
checks. The roles are associated to certain tasks
(e.g. backup or restore) instead of system calls.
The tokens are checked by setuid root utilities
to allow the task associated to a role.
Tru64 UNIX
AFAIK it has some token called priv, but they more
like AIX's roles: associated to certain task instead
of system calls.
Java 2
Permission - a token, which is used in security checks
in any code. A permission may be associated with a
user or a code.
The interesting idea here is the security domain: a code
is associated to a security domain with a given set of
permissions. When someone calls into a security domain
the permissions will be the intersection of the callee's
and the called domain's permissions. The problem of
"putpwent" is solved by an explicit call, where a code
may add permissions to the current set, if it exists in
its security domain.
[My interpretation to UNIX like systems: the called
program will run under the intersection of permissions
of the current user and the program's owner, unless it
is a setuid program, where it _may_ call setuid to use
all of the owner's rights.]
Linux capabilities
Capability - a token, which allows certain system calls.
A capability is associated with an image.
The notion of root still remains to provide backward
compability (it will be a special case in the security
checks.)
The capabilities are associated with files.
Suggestion:
-----------
In most of the existing systems the capabilities are associated
with users, since they are the entities, which can be identified.
There are several points where one needs this identification
outside the execution of code:
- auditing
- accounting
- logging
- applying quotas, resource restrictions
It would make sense to associate capabilities with users (e.g.
/etc/capabilities) and create new pseudousers for certain tasks.
The process should have setuid bit to this special user.
Pro:
- the accustomed behaviour of setuid bit remains unchanged (see KT#15)
- no need for new special bits in the file-system,
which would probably allocate a lot of unused space (see KT#59)
- can be tested/used without filesystem level support
- tar and cp will not change
Contra:
- "Most users do not have the authority to create new user
identities in the system." (EROS FAQ)
- "Access is dynamic, not static." (EROS FAQ) - one can not grant
a capability to access exactly one object created at runtime,
unless it creates a new userid for every new object.
The contra arguments (and the arguments beside filesystem based
capabilities) imply the creation of arbitary number of new capability
sets. I think it is unnecessary to solve our current problems (putpwent
and daemons) and would imply the creation of unmaintainable number
of new capability sets.
Furthermore Ingo Molnar's idea (see KT#15) on eliminating root can be
reached by eliminating the uid based security checks and creating a
root account with all of the capabilities set.
Further Ideas:
--------------
1. Later the capability system may be extended to support both filesystem
and user based capability sets as Java does. Contrary one may eliminate
the central capability database later and set the user's initial set
according to her/his home directory.
2. The dinamism and the details are not good enough in the filesystem based
solution, unless we map _everything_ into the filesystem. E.g. why should
we allow to a webserver to listen on any port under 1024 and not only at
80? Why should we allow to an executed process to write into our
directory and not only to a specified subdirectory of ours?
3. I do not know, if it can be achieved, but it would be an interesting idea
to apply the notion of Java's security domain: a capability set would be
associated to a code segment in the memory. If an entry point is called,
the code inside this segment would run with its own capabilities. (Much
like a system call into the kernel.) If it leaves this code segment, it
would drop the added capabilities. (POSIX 1003/1e 25.1 defines "Task
Bounding of a Capability", but it is examined only at exec() there.)
Let's see an example with user based capabilities on putpwent:
1. -rwsr-xr-x useradm useradm libpasswd.so
useradm user has the capability to modify the user database
libpasswd.so exports putpwent call, which modifies a user's
entry after the necessary parameter checks.
2. -rwxr-xr-x root root passwd
passwd provides the command line interface to change the
password. It runs under the user's capabilities, since
it is not a setuid application. Most of the code would
run in an unprivileged mode, so the security audit will
involve less source lines.
3. -rwxr-xr-x root root xpasswd
xpasswd provides the X11 interface to change the password.
It uses the same shared library as passwd and executes
the user interface with user capabilities.
The critical sections of the daemons could be also separated into
setuid shared libraries, thus they could be run under restricted
rights. E.g. xntpd would run under the normal xntpd user and use
libxntpdport.so to open a port under 1024, libxntpdtime.so to set
the system time. Both of the shared libraries would have only the
exact set of capabilities to accomplish their task.
One may apply the idea of capability aware code segment to the
filesystem based capability approach as well, or even throw
away both ideas and set the code segment's capabilities dinamically
at runtime.
EROS FAQ: http://www.eros-os.org/faq/basics.html
KT#15: http://www.linuxhq.de/kt/kt19990422_15.html
KT#59: http://www.linuxhq.de/kt/kt200003??_59.html
POSIX1003: http://www.guug.de/~winni/posix.1e/download.html
Best Regards,
Ákos Frohner
-- ------------------------------------------------------------------------- Akos Frohner | Eotvos Lorand University, Budapest, Hungary- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Fri Apr 07 2000 - 21:00:10 EST