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, ...@@ -636,6 +636,11 @@ void avc_audit(u32 ssid, u32 tsid,
NIPQUAD(a->u.net.daddr)); NIPQUAD(a->u.net.daddr));
if (a->u.net.port) if (a->u.net.port)
printk(" dest=%d", 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) } else if (a->u.net.port)
printk(" port=%d", a->u.net.port); printk(" port=%d", a->u.net.port);
if (a->u.net.skb) { if (a->u.net.skb) {
......
...@@ -2403,7 +2403,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in ...@@ -2403,7 +2403,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
err = socket_has_perm(current, sock, SOCKET__BIND); err = socket_has_perm(current, sock, SOCKET__BIND);
if (err) if (err)
return err; goto out;
/* /*
* If PF_INET, check name_bind permission for the port. * 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 ...@@ -2415,7 +2415,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
struct sockaddr_in *addr = (struct sockaddr_in *)address; struct sockaddr_in *addr = (struct sockaddr_in *)address;
unsigned short snum = ntohs(addr->sin_port); unsigned short snum = ntohs(addr->sin_port);
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
u32 sid; u32 sid, node_perm;
tsec = current->security; tsec = current->security;
isec = SOCK_INODE(sock)->i_security; isec = SOCK_INODE(sock)->i_security;
...@@ -2425,18 +2425,45 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in ...@@ -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, err = security_port_sid(sk->sk_family, sk->sk_type,
sk->sk_protocol, snum, &sid); sk->sk_protocol, snum, &sid);
if (err) if (err)
return err; goto out;
AVC_AUDIT_DATA_INIT(&ad,NET); AVC_AUDIT_DATA_INIT(&ad,NET);
ad.u.net.port = snum; ad.u.net.port = snum;
err = avc_has_perm(isec->sid, sid, err = avc_has_perm(isec->sid, sid,
isec->sclass, isec->sclass,
SOCKET__NAME_BIND, NULL, &ad); SOCKET__NAME_BIND, NULL, &ad);
if (err) 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;
} }
out:
return 0; return err;
} }
static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) 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[] = { ...@@ -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__CONNECTTO, "connectto" },
{ SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn" }, { SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn" },
{ SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom" }, { 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__FORK, "fork" },
{ SECCLASS_PROCESS, PROCESS__TRANSITION, "transition" }, { SECCLASS_PROCESS, PROCESS__TRANSITION, "transition" },
{ SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld" }, { SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld" },
......
...@@ -249,6 +249,7 @@ ...@@ -249,6 +249,7 @@
#define TCP_SOCKET__CONNECTTO 0x00400000UL #define TCP_SOCKET__CONNECTTO 0x00400000UL
#define TCP_SOCKET__NEWCONN 0x00800000UL #define TCP_SOCKET__NEWCONN 0x00800000UL
#define TCP_SOCKET__ACCEPTFROM 0x01000000UL #define TCP_SOCKET__ACCEPTFROM 0x01000000UL
#define TCP_SOCKET__NODE_BIND 0x02000000UL
#define UDP_SOCKET__RELABELTO 0x00000100UL #define UDP_SOCKET__RELABELTO 0x00000100UL
#define UDP_SOCKET__RECV_MSG 0x00080000UL #define UDP_SOCKET__RECV_MSG 0x00080000UL
...@@ -272,6 +273,7 @@ ...@@ -272,6 +273,7 @@
#define UDP_SOCKET__SEND_MSG 0x00100000UL #define UDP_SOCKET__SEND_MSG 0x00100000UL
#define UDP_SOCKET__RECVFROM 0x00020000UL #define UDP_SOCKET__RECVFROM 0x00020000UL
#define UDP_SOCKET__GETATTR 0x00000010UL #define UDP_SOCKET__GETATTR 0x00000010UL
#define UDP_SOCKET__NODE_BIND 0x00400000UL
#define RAWIP_SOCKET__RELABELTO 0x00000100UL #define RAWIP_SOCKET__RELABELTO 0x00000100UL
#define RAWIP_SOCKET__RECV_MSG 0x00080000UL #define RAWIP_SOCKET__RECV_MSG 0x00080000UL
...@@ -295,6 +297,7 @@ ...@@ -295,6 +297,7 @@
#define RAWIP_SOCKET__SEND_MSG 0x00100000UL #define RAWIP_SOCKET__SEND_MSG 0x00100000UL
#define RAWIP_SOCKET__RECVFROM 0x00020000UL #define RAWIP_SOCKET__RECVFROM 0x00020000UL
#define RAWIP_SOCKET__GETATTR 0x00000010UL #define RAWIP_SOCKET__GETATTR 0x00000010UL
#define RAWIP_SOCKET__NODE_BIND 0x00400000UL
#define NODE__TCP_RECV 0x00000001UL #define NODE__TCP_RECV 0x00000001UL
#define NODE__TCP_SEND 0x00000002UL #define NODE__TCP_SEND 0x00000002UL
......
...@@ -67,6 +67,7 @@ struct avc_audit_data { ...@@ -67,6 +67,7 @@ struct avc_audit_data {
struct sock *sk; struct sock *sk;
u16 port; u16 port;
u32 daddr; u32 daddr;
u32 saddr;
} net; } net;
int cap; int cap;
int ipc_id; 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