diff options
-rw-r--r-- | arch/arm/configs/msm_defconfig | 1 | ||||
-rw-r--r-- | net/Kconfig | 6 | ||||
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 38 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 32 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 32 |
5 files changed, 107 insertions, 2 deletions
diff --git a/arch/arm/configs/msm_defconfig b/arch/arm/configs/msm_defconfig index c1dc27023e97..faf9ebde382d 100644 --- a/arch/arm/configs/msm_defconfig +++ b/arch/arm/configs/msm_defconfig @@ -257,6 +257,7 @@ CONFIG_NET=y CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y +CONFIG_ANDROID_PARANOID_NETWORK=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y diff --git a/net/Kconfig b/net/Kconfig index cdb8fdef6c4a..5250712fae9f 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -61,6 +61,12 @@ source "net/netlabel/Kconfig" endif # if INET +config ANDROID_PARANOID_NETWORK + bool "Only allow certain groups to create sockets" + default y + help + none + config NETWORK_SECMARK bool "Security Marking" help diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 02b9baa1930b..ba8860e73cae 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -41,6 +41,15 @@ #include <net/bluetooth/bluetooth.h> +#ifdef CONFIG_ANDROID_PARANOID_NETWORK +#include <linux/android_aid.h> +#endif + +#ifndef CONFIG_BT_SOCK_DEBUG +#undef BT_DBG +#define BT_DBG(D...) +#endif + #define VERSION "2.15" /* Bluetooth sockets */ @@ -126,10 +135,39 @@ int bt_sock_unregister(int proto) } EXPORT_SYMBOL(bt_sock_unregister); +#ifdef CONFIG_ANDROID_PARANOID_NETWORK +static inline int current_has_bt_admin(void) +{ + return (!current_euid() || in_egroup_p(AID_NET_BT_ADMIN)); +} + +static inline int current_has_bt(void) +{ + return (current_has_bt_admin() || in_egroup_p(AID_NET_BT)); +} +# else +static inline int current_has_bt_admin(void) +{ + return 1; +} + +static inline int current_has_bt(void) +{ + return 1; +} +#endif + static int bt_sock_create(struct net *net, struct socket *sock, int proto) { int err; + if (proto == BTPROTO_RFCOMM || proto == BTPROTO_SCO || + proto == BTPROTO_L2CAP) { + if (!current_has_bt()) + return -EPERM; + } else if (!current_has_bt_admin()) + return -EPERM; + if (net != &init_net) return -EAFNOSUPPORT; diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 743f5542d65a..27410c339e19 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -116,6 +116,10 @@ #include <linux/mroute.h> #endif +#ifdef CONFIG_ANDROID_PARANOID_NETWORK +#include <linux/android_aid.h> +#endif + extern void ip_mc_drop_socket(struct sock *sk); /* The inetsw table contains everything that inet_create needs to @@ -258,6 +262,29 @@ static inline int inet_netns_ok(struct net *net, int protocol) return ipprot->netns_ok; } +#ifdef CONFIG_ANDROID_PARANOID_NETWORK +static inline int current_has_network(void) +{ + return (!current_euid() || in_egroup_p(AID_INET) || + in_egroup_p(AID_NET_RAW)); +} +static inline int current_has_cap(int cap) +{ + if (cap == CAP_NET_RAW && in_egroup_p(AID_NET_RAW)) + return 1; + return capable(cap); +} +# else +static inline int current_has_network(void) +{ + return 1; +} +static inline int current_has_cap(int cap) +{ + return capable(cap); +} +#endif + /* * Create an inet socket. */ @@ -273,6 +300,9 @@ static int inet_create(struct net *net, struct socket *sock, int protocol) int try_loading_module = 0; int err; + if (!current_has_network()) + return -EACCES; + if (unlikely(!inet_ehash_secret)) if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) build_ehash_secret(); @@ -325,7 +355,7 @@ lookup_protocol: } err = -EPERM; - if (answer->capability > 0 && !capable(answer->capability)) + if (answer->capability > 0 && !current_has_cap(answer->capability)) goto out_rcu_unlock; err = -EAFNOSUPPORT; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 9c8309ed35cf..c30f24bf2ccd 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -62,6 +62,10 @@ #include <asm/system.h> #include <linux/mroute6.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"); @@ -83,6 +87,29 @@ 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->euid || in_egroup_p(AID_INET) || + in_egroup_p(AID_NET_RAW)); +} +static inline int current_has_cap(int cap) +{ + if (cap == CAP_NET_RAW && in_egroup_p(AID_NET_RAW)) + return 1; + return capable(cap); +} +# else +static inline int current_has_network(void) +{ + return 1; +} +static inline int current_has_cap(int cap) +{ + return capable(cap); +} +#endif + static int inet6_create(struct net *net, struct socket *sock, int protocol) { struct inet_sock *inet; @@ -95,6 +122,9 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol) int try_loading_module = 0; int err; + if (!current_has_network()) + return -EACCES; + if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM && !inet_ehash_secret) @@ -146,7 +176,7 @@ lookup_protocol: } err = -EPERM; - if (answer->capability > 0 && !capable(answer->capability)) + if (answer->capability > 0 && !current_has_cap(answer->capability)) goto out_rcu_unlock; sock->ops = answer->ops; |