From: Robert Love Date: Wed, 15 Oct 2008 19:35:44 +0000 (-0400) Subject: Paranoid network. X-Git-Tag: firefly_0821_release~11745 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=910b063a7e65960c1bb9cc4e91e9273b020709da;p=firefly-linux-kernel-4.4.55.git Paranoid network. With CONFIG_ANDROID_PARANOID_NETWORK, require specific uids/gids to instantiate network sockets. Signed-off-by: Robert Love paranoid networking: Use in_egroup_p() to check group membership The previous group_search() caused trouble for partners with module builds. in_egroup_p() is also cleaner. Signed-off-by: Nick Pelly Fix 2.6.29 build. Signed-off-by: Arve Hjønnevåg net: Fix compilation of the IPv6 module Fix compilation of the IPv6 module -- current->euid does not exist anymore, current_euid() is what needs to be used. Signed-off-by: Steinar H. Gunderson --- 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 041c35edb763..94312cb3a57d 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -79,6 +79,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 8cfb5a849841..1707efb7cb0f 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -41,6 +41,15 @@ #include +#ifdef CONFIG_ANDROID_PARANOID_NETWORK +#include +#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 57737b8d1711..b395f7d34bd3 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -116,6 +116,9 @@ #include #endif +#ifdef CONFIG_ANDROID_PARANOID_NETWORK +#include +#endif /* The inetsw table contains everything that inet_create needs to * build a new socket. @@ -258,6 +261,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 +299,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 +354,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 e127a32f9540..0a883bf68ceb 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -62,6 +62,10 @@ #include #include +#ifdef CONFIG_ANDROID_PARANOID_NETWORK +#include +#endif + MODULE_AUTHOR("Cast of dozens"); MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); MODULE_LICENSE("GPL"); @@ -95,6 +99,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; @@ -107,6 +134,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) @@ -158,7 +188,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;