Skip to content
Snippets Groups Projects
Commit 8deec616 authored by Robert Love's avatar Robert Love Committed by Brian Swetland
Browse files

android: paranoid_network: security around AF_INET socket creation


Require the "inet" group (gid 3003) in order to create an AF_INET or
AF_INET6 socket.

Configurable with the ANDROID_PARANOID_NETWORK configure option.

Also, for cleanliness, bring the similar code for AF_BLUETOOTH sockets
under the same regime.

Signed-off-by: default avatarRobert Love <rlove@google.com>
parent d3f36387
No related merge requests found
......@@ -86,10 +86,8 @@ config ANDROID_TIMED_GPIO
depends on GENERIC_GPIO
default y
config ANDROID_PARANOID_BLUETOOTH
bool "Require gid AID_NET_BT [_ADMIN] to create AF_BLUETOOTH sockets"
config ANDROID_PARANOID_NETWORK
bool "Only allow certain groups to create sockets"
default y
help
none
endmenu
......@@ -19,5 +19,6 @@
/* AIDs that the kernel treats differently */
#define AID_NET_BT_ADMIN 3001
#define AID_NET_BT 3002
#define AID_INET 3003
#endif
......@@ -43,7 +43,7 @@
#include <net/bluetooth/bluetooth.h>
#ifdef CONFIG_ANDROID_PARANOID_BLUETOOTH
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
#include <linux/android_aid.h>
#endif
......@@ -138,14 +138,27 @@ static void bt_reclassify_sock_lock(struct socket *sock, int proto)
&bt_lock_key[proto]);
}
#ifdef CONFIG_ANDROID_PARANOID_BLUETOOTH
static int is_bt_admin(void) {
return !current->uid || current->gid == AID_NET_BT_ADMIN ||
groups_search(current->group_info, AID_NET_BT_ADMIN);
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
static inline int current_has_bt_admin(void)
{
return (!current->uid || current->gid == AID_NET_BT_ADMIN ||
groups_search(current->group_info, AID_NET_BT_ADMIN));
}
static inline int current_has_bt(void)
{
return (current_has_bt_admin() || current->gid == AID_NET_BT ||
groups_search(current->group_info, AID_NET_BT));
}
static int is_bt_user_or_admin(void) {
return is_bt_admin() || current->gid == AID_NET_BT ||
groups_search(current->group_info, AID_NET_BT);
# else
static inline int current_has_bt_admin(void)
{
return 1;
}
static inline int current_has_bt(void)
{
return 1;
}
#endif
......@@ -153,12 +166,12 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto)
{
int err;
#ifdef CONFIG_ANDROID_PARANOID_BLUETOOTH
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
if (proto == BTPROTO_RFCOMM || proto == BTPROTO_SCO ||
proto == BTPROTO_L2CAP) {
if (!is_bt_user_or_admin())
if (!current_has_bt())
return -EPERM;
} else if (!is_bt_admin()) {
} else if (!current_has_bt_admin()) {
return -EPERM;
}
#endif
......
......@@ -116,6 +116,10 @@
#include <linux/mroute.h>
#endif
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
#include <linux/android_aid.h>
#endif
DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly;
extern void ip_mc_drop_socket(struct sock *sk);
......@@ -243,6 +247,19 @@ void build_ehash_secret(void)
}
EXPORT_SYMBOL(build_ehash_secret);
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
static inline int current_has_network(void)
{
return (!current->uid || current->gid == AID_INET ||
groups_search(current->group_info, AID_INET));
}
# else
static inline int current_has_network(void)
{
return 1;
}
#endif
/*
* Create an inet socket.
*/
......@@ -262,6 +279,9 @@ static int inet_create(struct net *net, struct socket *sock, int protocol)
if (net != &init_net)
return -EAFNOSUPPORT;
if (!current_has_network())
return -EACCES;
if (sock->type != SOCK_RAW &&
sock->type != SOCK_DGRAM &&
!inet_ehash_secret)
......
......@@ -62,6 +62,10 @@
#include <asm/uaccess.h>
#include <asm/system.h>
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
#include <linux/android_aid.h>
#endif
MODULE_AUTHOR("Cast of dozens");
MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
MODULE_LICENSE("GPL");
......@@ -79,6 +83,19 @@ static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
}
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
static inline int current_has_network(void)
{
return (!current->uid || current->gid == AID_INET ||
groups_search(current->group_info, AID_INET));
}
# else
static inline int current_has_network(void)
{
return 1;
}
#endif
static int inet6_create(struct net *net, struct socket *sock, int protocol)
{
struct inet_sock *inet;
......@@ -95,6 +112,9 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol)
if (net != &init_net)
return -EAFNOSUPPORT;
if (!current_has_network())
return -EACCES;
if (sock->type != SOCK_RAW &&
sock->type != SOCK_DGRAM &&
!inet_ehash_secret)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment