From: James Morris 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. --- 25-akpm/security/selinux/avc.c | 5 ++ 25-akpm/security/selinux/hooks.c | 39 ++++++++++++++++--- 25-akpm/security/selinux/include/av_perm_to_string.h | 3 + 25-akpm/security/selinux/include/av_permissions.h | 3 + 25-akpm/security/selinux/include/avc.h | 1 5 files changed, 45 insertions(+), 6 deletions(-) diff -puN security/selinux/avc.c~selinux-04-node_bind-control security/selinux/avc.c --- 25/security/selinux/avc.c~selinux-04-node_bind-control Fri Jan 9 12:49:33 2004 +++ 25-akpm/security/selinux/avc.c Fri Jan 9 12:49:33 2004 @@ -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 -puN security/selinux/hooks.c~selinux-04-node_bind-control security/selinux/hooks.c --- 25/security/selinux/hooks.c~selinux-04-node_bind-control Fri Jan 9 12:49:33 2004 +++ 25-akpm/security/selinux/hooks.c Fri Jan 9 12:49:33 2004 @@ -2403,7 +2403,7 @@ static int selinux_socket_bind(struct so 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 so 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 so 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 -puN security/selinux/include/avc.h~selinux-04-node_bind-control security/selinux/include/avc.h --- 25/security/selinux/include/avc.h~selinux-04-node_bind-control Fri Jan 9 12:49:33 2004 +++ 25-akpm/security/selinux/include/avc.h Fri Jan 9 12:49:33 2004 @@ -67,6 +67,7 @@ struct avc_audit_data { struct sock *sk; u16 port; u32 daddr; + u32 saddr; } net; int cap; int ipc_id; diff -puN security/selinux/include/av_permissions.h~selinux-04-node_bind-control security/selinux/include/av_permissions.h --- 25/security/selinux/include/av_permissions.h~selinux-04-node_bind-control Fri Jan 9 12:49:33 2004 +++ 25-akpm/security/selinux/include/av_permissions.h Fri Jan 9 12:49:33 2004 @@ -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 -puN security/selinux/include/av_perm_to_string.h~selinux-04-node_bind-control security/selinux/include/av_perm_to_string.h --- 25/security/selinux/include/av_perm_to_string.h~selinux-04-node_bind-control Fri Jan 9 12:49:33 2004 +++ 25-akpm/security/selinux/include/av_perm_to_string.h Fri Jan 9 12:49:33 2004 @@ -46,6 +46,9 @@ static struct av_perm_to_string av_perm_ { 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" }, _