From eeb6c00c93308cee91d46a5bfc6652f258a1f3cc Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Sat, 17 Feb 2007 15:48:03 +0000 Subject: security: Move CAP_NET_BIND_SERVICE checks from af_inet/af_inet6 to dummy_socket_bind. --- net/ipv4/af_inet.c | 2 ++ net/ipv6/af_inet6.c | 2 ++ security/dummy.c | 22 ++++++++++++++++++++++ 3 files changed, 26 insertions(+), 0 deletions(-) diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index cf358c8..d75a2c5 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -431,9 +431,11 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) goto out; snum = ntohs(addr->sin_port); +#ifndef CONFIG_SECURITY_NETWORK err = -EACCES; if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) goto out; +#endif /* We keep a pair of addresses. rcv_saddr is the one * used by hash lookups, and saddr is used for transmit. diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3585d8f..768989d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -262,8 +262,10 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) return -EINVAL; snum = ntohs(addr->sin6_port); +#ifndef CONFIG_SECURITY_NETWORK if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) return -EACCES; +#endif lock_sock(sk); diff --git a/security/dummy.c b/security/dummy.c index 558795b..6d90354 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -29,6 +29,8 @@ #include #include +#include + static int dummy_ptrace (struct task_struct *parent, struct task_struct *child) { return 0; @@ -718,6 +720,26 @@ static int dummy_socket_post_create (struct socket *sock, int family, int type, static int dummy_socket_bind (struct socket *sock, struct sockaddr *address, int addrlen) { + switch (address->sa_family) { +#ifdef CONFIG_INET + case PF_INET: { + struct sockaddr_in *addr = (struct sockaddr_in *)address; + unsigned short snum; + snum = ntohs((addr->sin_port)); + if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) + return -EACCES; + break; + } + case PF_INET6: { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)address; + unsigned short snum; + snum = ntohs(addr->sin6_port); + if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) + return -EACCES; + break; + } +#endif + } return 0; } -- 1.5.0.1