How to get Android process working with CAP_NET_ADMIN feature

I have an Android activity using the JNI library that uses netlink commands to configure the network interface (in this case, the socketcan interface). If I run this operation, the network interface configuration will end with an EPERM error from RTNETLINK. For successful execution of commands, for successful completion, CAP_NET_ADMIN is required. Thus, the code runs as root, and also runs as root, and then is limited only by CAP_NET_ADMIN with capset .

I added the following permissions for the application manifest, which gave me the impression that NET_ADMIN would be provided to my process:

<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 feature, which caused network commands to fail with EPERM.

In various search queries that I made on this topic, I found hints of the possibility of using this feature. e.g. 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 is not like my system.

NOTE. I am starting the system and the kernel, modified by the chipset provider, so it is possible that something has been changed, which will prevent this from working.

Somebody knows

  • Should this work?
  • What other steps are needed to add features to the process?
  • Is it possible?
+4
source share
2 answers

It turns out that Android is modifying the kernel capabilities system, which allows you to test specific capabilities based on the group identifier. Unfortunately, the changes made do not cover all cases. To solve the problem I encountered, I changed the cap_netlink_recv check to use the modified Android cap_capability . This allows users of the net_link group to receive CAP_NET_LINK capabilities .

This change seems to be in the spirit of the changes made to the Android kernel and works for my situation.

 diff --git a/security/commoncap.cb/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 
+4
source

In fact, in the network path there is no verification of additional permissions for kernel versions prior to v3.1-18-gfd77846 .

Initially, it would be nice to replace cap_raised completely, so here I preferred to add a similar check as such to cap_capable . Other possible cap are CAP_SYS_ADMIN , CAP_AUDIT_CONTROL and CAP_AUDIT_WRITE , but they are not network related. Note that since commit is the above, it ultimately ends up calling cap_capable (via capable ).

Patch:

 diff --git a/security/commoncap.cb/security/commoncap.c index 8bfbd13..485245a 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -63,6 +63,10 @@ int cap_netlink_send(struct sock *sk, struct sk_buff *skb) int cap_netlink_recv(struct sk_buff *skb, int cap) { +#ifdef CONFIG_ANDROID_PARANOID_NETWORK + if (cap == CAP_NET_ADMIN && in_egroup_p(AID_NET_ADMIN)) + return 0; +#endif if (!cap_raised(current_cap(), cap)) return -EPERM; return 0; 

For those looking at CAP_NET_RAW , for this you need to be in the net_raw group. Either add this group to the existing android.permission.NET_ADMIN permission, or apply the following frame patch:

 diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 1e7dcf7..07f5d94 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -927,6 +927,12 @@ android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:protectionLevel="signature" /> + <!-- Allows access to raw sockets, allowing full network access and spoofing. + @hide --> + <permission android:name="android.permission.NET_RAW" + android:permissionGroup="android.permission-group.SYSTEM_TOOLS" + android:protectionLevel="signature" /> + <!-- Allows registration for remote audio playback. @hide --> <permission android:name="android.permission.REMOTE_AUDIO_PLAYBACK" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" diff --git a/data/etc/platform.xml b/data/etc/platform.xml index 47cb7ab..9c209c3 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -82,6 +82,10 @@ <group gid="net_admin" /> </permission> + <permission name="android.permission.NET_RAW" > + <group gid="net_raw" /> + </permission> + <!-- The group that /cache belongs to, linked to the permission set on the applications that can access /cache --> <permission name="android.permission.ACCESS_CACHE_FILESYSTEM" > 
0
source

Source: https://habr.com/ru/post/1441709/


All Articles