aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-01-18 18:37:54 -0800
committerLinus Torvalds <torvalds@home.osdl.org>2004-01-18 18:37:54 -0800
commit0129565dcb026535035409875fae2ba1bb1a8b55 (patch)
tree6bcf135d9def2f9ff936cfc7fc74502077e8e13a /security
parent85941b90bd308e89217f1b601dc9e048df303e70 (diff)
downloadhistory-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.c5
-rw-r--r--security/selinux/hooks.c39
-rw-r--r--security/selinux/include/av_perm_to_string.h3
-rw-r--r--security/selinux/include/av_permissions.h3
-rw-r--r--security/selinux/include/avc.h1
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;