Commit 0129565d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[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.
parent 85941b90
......@@ -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) {
......
......@@ -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)
......
......@@ -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" },
......
......@@ -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
......
......@@ -67,6 +67,7 @@ struct avc_audit_data {
struct sock *sk;
u16 port;
u32 daddr;
u32 saddr;
} net;
int cap;
int ipc_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment