How do I get an Android Process running with the CAP_NET_ADMIN capability
android, android-permissions
Solution
It turns out that Android modifies the kernel capability system to allow verification of specific capabilities based on group-id. Unfortunately the modifications made don't seem to cover all cases. To resolve the problem I was having, I modified the cap_netlink_recv check to use the Android modified cap_capability call. This allows users in the net_link group to obtain CAP_NET_LINK capabilities.
This change seems to be within the spirit of the modifications made to the Android kernel, and works for my situation.
diff --git a/security/commoncap.c b/security/commoncap.c
index ccfe568..f069f8d 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -56,21 +56,23 @@
}
}
int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
{
» return 0;
}
int cap_netlink_recv(struct sk_buff *skb, int cap)
{
-» if (!cap_raised(current_cap(), cap))
+» if (cap_capable(current, current_cred(),
+» » » current_cred()->user->user_ns, cap,
+» » » SECURITY_CAP_NOAUDIT) != 0)
» » return -EPERM;
» return 0;
}
EXPORT_SYMBOL(cap_netlink_recv);
/**
* cap_capable - Determine whether a task has a particular effective capability
* @tsk: The task to query
* @cred: The credentials to use
* @ns: The user namespace in which we need the capability
Problem
I have an Android activity utilizing a JNI library that uses netlink commands to configure a network interface (in this case a socketcan interface). If I run the activity, the network interface configuration fails with an EPERM error from RTNETLINK. The commands that are failing require the CAP_NET_ADMIN capability in order to successfully complete. As such running the code as root succeeds, and also running as root and then limiting the capabilities to only CAP_NET_ADMIN using capset. I added the following permissions to the applications manifest that gave me the impression that my process would be given the NET_ADMIN capabilities: ``` <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.NET_ADMIN" /> ``` This put the process in the inet and net_admin groups, but the process did not receive the CAP_NET_ADMIN capability resulting in the netlink commands failing with EPERM. In various searches I have made on this topic I have found hints that the capability should be applied. eg, from http://elinux.org/Android_Security ``` #define GID Capability AID_NET_BT_ADMIN 3001 Can create an RFCOMM, SCO, or L2CAPP Bluetooth socket AID_NET_BT 3002 Can create a Bluetooth socket AID_INET 3003 Can create IPv4 or IPv6 socket AID_NET_RAW 3004 Can create certain kinds of IPv4 sockets?? AID_NET_ADMIN* 3005 Allow CAP_NET_ADMIN permissions for process ``` Unfortunately, this doesn't seem to apply to my system. NOTE: I am running with a system and kernel modified by a chipset vendor, so it is possible that something has been modified that stops this from working. Does anyone know - If this should just work? - What other steps are required to add the capability to a process? - Whether it is even possible?