2.6.25: access permission filesystem 0.21
Subsystems (4)
PATCH 1/1 2.6.25: access permission filesystem 0.21
This patch adds a new permission managing file system. Furthermore, it adds two modules, which make use of this file system.
One module allows granting capabilities based on user-/groupid. The second module allows to grant access to lower numbered ports based on user-/groupid, too.
Changes:
- updated to 2.6.25
- Add ignore CAP_NET_BIND_SERVICE option
- Specify license as "GPL v2"
- Fix access to nonexistent file
- Prevent changing file attributes by anybody
This patch is available at:
<http://www.olafdietsche.de/linux/accessfs/>
Regards, Olaf.
Documentation/filesystems/accessfs.txt new file +41 -0
@@ -0,0 +1,41 @@ +Accessfs is a permission managing filesystem. It allows to control access to +system resources, based on file permissions. The recommended mount point for +this file-system is /proc/access, which will appear automatically in the +/proc filesystem. + +Currently there are two modules using accessfs, userports and usercaps. + +With userports, you will be able to control access to IP ports based +on user-/groupid. + +There's no need anymore to run internet daemons as root. You can +individually configure which user/program can bind to protected ports +(by default, below 1024). + +For example, you can say, user www is allowed to bind to port 80 or +user mail is allowed to bind to port 25. Then, you can run apache as +user www and sendmail as user mail. Now, you don't have to rely on +apache or sendmail giving up superuser rights to enhance security. + +To use this option, you need to mount the access file system +and do a chown on the appropriate ports: + +# mount -t accessfs none /proc/access +# chown www /proc/access/net/ip/bind/80 +# chown mail /proc/access/net/ip/bind/25 + +You can grant access to a group for individual ports as well. Just say: + +# chgrp lp /proc/access/net/ip/bind/515 +# chown g+x /proc/access/net/ip/bind/515 + +With usercaps, you will be able to grant capabilities based on +user-/groupid (root by default). + +For example you can create a group raw and change the capability +net_raw to this group: + +# chgrp raw /proc/access/capabilities/net_raw +# chmod ug+x /proc/access/capabilities/net_raw +# chgrp raw /sbin/ping +# chmod u-s /sbin/ping; chmod g+s /sbin/ping
fs/Kconfig +1 -0
@@ -1462,6 +1462,7 @@ config ROMFS_FS If you don't know whether you need it, then you don't need it: answer N. +source "fs/accessfs/Kconfig" config SYSV_FS tristate "System V/Xenix/V7/Coherent file system support"
fs/Makefile +1 -0
@@ -119,3 +119,4 @@ obj-$(CONFIG_HPPFS) += hppfs/ obj-$(CONFIG_DEBUG_FS) += debugfs/ obj-$(CONFIG_OCFS2_FS) += ocfs2/ obj-$(CONFIG_GFS2_FS) += gfs2/ +obj-$(CONFIG_ACCESS_FS) += accessfs/
fs/accessfs/Kconfig new file +64 -0
64 lines not on this page · raw message
fs/accessfs/Makefile new file +11 -0
@@ -0,0 +1,11 @@ +# +# Makefile for the linux accessfs routines. +# + +obj-$(CONFIG_ACCESS_FS) += accessfs.o +obj-$(CONFIG_ACCESSFS_USER_CAPABILITIES) += usercaps.o +obj-$(CONFIG_ACCESSFS_USER_PORTS) += userports.o + +accessfs-objs := inode.o +usercaps-objs := capabilities.o +userports-objs := ip.o
fs/accessfs/capabilities.c new file +107 -0
107 lines not on this page · raw message
fs/accessfs/inode.c new file +434 -0
434 lines not on this page · raw message
fs/accessfs/ip.c new file +98 -0
98 lines not on this page · raw message
include/linux/accessfs_fs.h new file +42 -0
42 lines not on this page · raw message
include/net/sock.h +43 -0
47 lines not on this page · raw message
net/Kconfig +12 -0
@@ -65,6 +65,18 @@ config INET if INET source "net/ipv4/Kconfig" source "net/ipv6/Kconfig" + +config NET_HOOKS + bool "IP: Networking hooks (Experimental)" + depends on INET && EXPERIMENTAL + default n + help + This option enables other kernel parts or modules to hook into the + networking area and provide fine grained control over the access to + IP ports. + + If you're unsure, say N. + source "net/netlabel/Kconfig" endif # if INET
net/Makefile +1 -0
@@ -53,6 +53,7 @@ obj-$(CONFIG_NETLABEL) += netlabel/ obj-$(CONFIG_IUCV) += iucv/ obj-$(CONFIG_RFKILL) += rfkill/ obj-$(CONFIG_NET_9P) += 9p/ +obj-$(CONFIG_NET_HOOKS) += hooks.o ifeq ($(CONFIG_NET),y) obj-$(CONFIG_SYSCTL) += sysctl_net.o
net/hooks.c new file +55 -0
55 lines not on this page · raw message
net/ipv4/af_inet.c +1 -1
@@ -466,7 +466,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) snum =ntohs (addr->sin_port); err = -EACCES ; -if (snum && snum <PROT_SOCK && !capable (CAP_NET_BIND_SERVICE )) +if (ip_prot_sock (sock, uaddr, addr_len)) goto out;/* We keep a pair of addresses. rcv_saddr is the one
net/ipv6/af_inet6.c +1 -1
@@ -264,7 +264,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)return -EINVAL ; snum =ntohs (addr->sin6_port); -if (snum && snum <PROT_SOCK && !capable (CAP_NET_BIND_SERVICE )) +if (ip6_prot_sock (sock, uaddr, addr_len))return -EACCES ;lock_sock (sk);
Quoted 4 lines · --- Olaf Dietsche
This patch adds a new permission managing file system. Furthermore, it adds two modules, which make use of this file system.
One module allows granting capabilities based on user-/groupid.
Hmm. The primary purpose of the capability mechanism, according to the POSIX P1003.1e/2c working group*, is to separate the privilege mechanism from the userid mechanism. You are now reintegrating them two mechanims, albiet differently than they were integrated before. You can already achieve this end using filesystem based capabilties and mode bits and/or ACLs, so why the change?
Quoted 3 lines
The
second module allows to grant access to lower numbered ports based on user-/groupid, too.
Woof. As reasonable as mode bits on ports seems, there's an awful lot of tradition associated with the privileged port model. I can see the value in it, I've actually implemented it in the past in the Unix world, but I have never seen anyone willing to take advantage of the scheme.
-----
* As I'm the only member of that working group who ever pipes up here, you'll have to take my word for it. (smiley)
Casey Schaufler
[email protected]
Quoted 7 lines · Casey Schaufler
Quoted 4 lines · --- Olaf Dietsche
This patch adds a new permission managing file system. Furthermore, it adds two modules, which make use of this file system.
One module allows granting capabilities based on user-/groupid.
Quoted 7 lines
Hmm. The primary purpose of the capability mechanism, according to the POSIX P1003.1e/2c working group*, is to separate the privilege mechanism from the userid mechanism. You are now reintegrating them two mechanims, albiet differently than they were integrated before. You can already achieve this end using filesystem based capabilties and mode bits and/or ACLs, so why the change?
This idea is from 2002, when there were neither filesystem based capabilties nor ACLs. But since even I never used it, see it as an interesting excercise.
Quoted 9 lines
Quoted 3 lines
The
second module allows to grant access to lower numbered ports based on user-/groupid, too.Woof. As reasonable as mode bits on ports seems, there's an awful lot of tradition associated with the privileged port model. I can see the value in it, I've actually implemented it in the past in the Unix world, but I have never seen anyone willing to take advantage of the scheme.
Well, I'm not in the tradition business :-) but it's fun to do these things and even useful in this case.
Regards, Olaf
Quoted 2 lines · On Mon, 12 May 2008 22:59:32 +0200 Olaf Dietsche wrote:
This patch adds a new permission managing file system. Furthermore, it adds two modules, which make use of this file system.
(attachment fragments copied as needed for comments:)
fs/accessfs/Kconfig:
+config ACCESSFS_USER_PORTS
+ tristate "User permission based IP ports"
+ depends on ACCESS_FS
+ select NET_HOOKS
+ default n
+ help
+ If you say Y here, you will be able to control access to IP ports + based on user-/groupid. For this to work, you must say Y + to CONFIG_NET_HOOKS.
+
+ If you're unsure, say N.
Just spell out userid instead of using "user-". The hyphen is only saving one character, so just make it clearer by spelling it out. (Several instances of this, including in the Documentation.)
This config option should probably also depend on INET since it selects NET_HOOKS and NET_HOOKS depends on INET (and since select won't follow any dependency chain).
+config ACCESSFS_IGNORE_NET_BIND_SERVICE
+ bool "Ignore CAP_NET_BIND_SERVICE capability"
+ depends on ACCESSFS_USER_PORTS
+ default n
+ help
+ This option lets you decide, wether a user with
whether
Oh. That line ends with a space. Please check all Kconfig and source file lines to make sure that they do not end with whitespace.
+ CAP_NET_BIND_SERVICE capability is able to override
+ your userport configuration.
+
+ If you build this as a module, you can specify this
+ option at module load time (ignore_net_bind_service).
+
+ If you're unsure, say n.
Have the networking people commented on the NET_HOOKS and their function methods?
inode.c:
+static inline void accessfs_readdir_aux(struct file *filp,
+ struct accessfs_direntry *dir,
+ int start, void *dirent,
+ filldir_t filldir)
is rather large to be inlined. Why do that?
+int accessfs_register(struct accessfs_direntry *dir, const char *name,
+ struct access_attr *attr)
+{
+ int err;
+ if (dir == 0)
+ return -EINVAL;
Don't check for 0, check for NULL (when it's a pointer being tested). So use either
if (dir == NULL) or if (!dir)
(several of these seen)
+static int __init init_accessfs_fs(void)
+{
+
+ /* create mount point for accessfs */
+ mountdir = proc_mkdir("access",&proc_root);
space after comma.
+ return register_filesystem(&accessfs_fs_type);
+}
+
+static void __exit exit_accessfs_fs(void)
+{
+ unregister_filesystem(&accessfs_fs_type);
+ remove_proc_entry("access",&proc_root);
ditto.
+}
ip.c:
+ bind_to_port = kmalloc(max_prot_sock * sizeof(*bind_to_port),
+ GFP_KERNEL);
+ if (bind_to_port == 0)
+ return -ENOMEM;
Test pointer for NULL or use !bind_to_port.
+static void __exit exit_ip(void)
+{
+ struct accessfs_direntry *dir = accessfs_make_dirpath("net/ip/bind");
+ int i;
+ net_hooks_unregister(&ip_net_ops);
+ for (i = 1; i < max_prot_sock; ++i) {
+ char buf[sizeof("65536")];
buf[sizeof("65536") + 1]; ???+ sprintf(buf, "%d", i);
+ accessfs_unregister(dir, buf);
+ }
Documentation/filesystems/accessfs.txt:
Change "user-/" to "userid/".
---
~Randy