diff options
author | Andrew Morton <akpm@osdl.org> | 2004-01-18 18:37:54 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@home.osdl.org> | 2004-01-18 18:37:54 -0800 |
commit | 0129565dcb026535035409875fae2ba1bb1a8b55 (patch) | |
tree | 6bcf135d9def2f9ff936cfc7fc74502077e8e13a /security | |
parent | 85941b90bd308e89217f1b601dc9e048df303e70 (diff) | |
download | history-0129565dcb026535035409875fae2ba1bb1a8b55.tar.gz |
[PATCH] selinux: Add node_bind control
From: James Morris <jmorris@redhat.com>
This patch adds a new SELinux access control, node_bind, which can be used
to restrict the local IP address to which an application may bind.
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/avc.c | 5 | ||||
-rw-r--r-- | security/selinux/hooks.c | 39 | ||||
-rw-r--r-- | security/selinux/include/av_perm_to_string.h | 3 | ||||
-rw-r--r-- | security/selinux/include/av_permissions.h | 3 | ||||
-rw-r--r-- | security/selinux/include/avc.h | 1 |
5 files changed, 45 insertions, 6 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 0871fa4df90612..b6c792db23efbc 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -636,6 +636,11 @@ void avc_audit(u32 ssid, u32 tsid, NIPQUAD(a->u.net.daddr)); if (a->u.net.port) printk(" dest=%d", a->u.net.port); + } else if (a->u.net.saddr) { + printk(" saddr=%d.%d.%d.%d", + NIPQUAD(a->u.net.saddr)); + if (a->u.net.port) + printk(" src=%d", a->u.net.port); } else if (a->u.net.port) printk(" port=%d", a->u.net.port); if (a->u.net.skb) { diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 842b130950a4c2..ec980b81264d42 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2403,7 +2403,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in err = socket_has_perm(current, sock, SOCKET__BIND); if (err) - return err; + goto out; /* * If PF_INET, check name_bind permission for the port. @@ -2415,7 +2415,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in struct sockaddr_in *addr = (struct sockaddr_in *)address; unsigned short snum = ntohs(addr->sin_port); struct sock *sk = sock->sk; - u32 sid; + u32 sid, node_perm; tsec = current->security; isec = SOCK_INODE(sock)->i_security; @@ -2425,18 +2425,45 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in err = security_port_sid(sk->sk_family, sk->sk_type, sk->sk_protocol, snum, &sid); if (err) - return err; + goto out; AVC_AUDIT_DATA_INIT(&ad,NET); ad.u.net.port = snum; err = avc_has_perm(isec->sid, sid, isec->sclass, SOCKET__NAME_BIND, NULL, &ad); if (err) - return err; + goto out; + } + + switch(sk->sk_protocol) { + case IPPROTO_TCP: + node_perm = TCP_SOCKET__NODE_BIND; + break; + + case IPPROTO_UDP: + node_perm = UDP_SOCKET__NODE_BIND; + break; + + default: + node_perm = RAWIP_SOCKET__NODE_BIND; + break; } + + err = security_node_sid(PF_INET, &addr->sin_addr.s_addr, + sizeof(addr->sin_addr.s_addr), &sid); + if (err) + goto out; + + AVC_AUDIT_DATA_INIT(&ad,NET); + ad.u.net.port = snum; + ad.u.net.saddr = addr->sin_addr.s_addr; + err = avc_has_perm(isec->sid, sid, + isec->sclass, node_perm, NULL, &ad); + if (err) + goto out; } - - return 0; +out: + return err; } static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index 69ec417d9b0ebe..0c616793b9b55f 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h @@ -46,6 +46,9 @@ static struct av_perm_to_string av_perm_to_string[] = { { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto" }, { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn" }, { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom" }, + { SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind" }, + { SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind" }, + { SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind" }, { SECCLASS_PROCESS, PROCESS__FORK, "fork" }, { SECCLASS_PROCESS, PROCESS__TRANSITION, "transition" }, { SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld" }, diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index 6cef301cbdbef0..72e53d4bc78745 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h @@ -249,6 +249,7 @@ #define TCP_SOCKET__CONNECTTO 0x00400000UL #define TCP_SOCKET__NEWCONN 0x00800000UL #define TCP_SOCKET__ACCEPTFROM 0x01000000UL +#define TCP_SOCKET__NODE_BIND 0x02000000UL #define UDP_SOCKET__RELABELTO 0x00000100UL #define UDP_SOCKET__RECV_MSG 0x00080000UL @@ -272,6 +273,7 @@ #define UDP_SOCKET__SEND_MSG 0x00100000UL #define UDP_SOCKET__RECVFROM 0x00020000UL #define UDP_SOCKET__GETATTR 0x00000010UL +#define UDP_SOCKET__NODE_BIND 0x00400000UL #define RAWIP_SOCKET__RELABELTO 0x00000100UL #define RAWIP_SOCKET__RECV_MSG 0x00080000UL @@ -295,6 +297,7 @@ #define RAWIP_SOCKET__SEND_MSG 0x00100000UL #define RAWIP_SOCKET__RECVFROM 0x00020000UL #define RAWIP_SOCKET__GETATTR 0x00000010UL +#define RAWIP_SOCKET__NODE_BIND 0x00400000UL #define NODE__TCP_RECV 0x00000001UL #define NODE__TCP_SEND 0x00000002UL diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 3690fe1f3b3800..9ecb739c802360 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -67,6 +67,7 @@ struct avc_audit_data { struct sock *sk; u16 port; u32 daddr; + u32 saddr; } net; int cap; int ipc_id; |