我有一个利用JNI库的Android活动,该库使用netlink命令配置网络接口(在本例中为socketcan接口)。如果我运行活动,网络接口配置将失败,RTNETLINK出现 EPERM 错误。失败的命令需要 CAP_NET_ADMIN 功能才能成功完成。因此,以root身份运行代码成功,并以root身份运行,然后使用 capset 将功能限制为仅 CAP_NET_ADMIN 。
我在应用程序清单中添加了以下权限,让我觉得我的进程将获得NET_ADMIN功能:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NET_ADMIN" />
这会将流程置于 inet 和 net_admin 组中,但该流程未收到CAP_NET_ADMIN功能,导致netlink命令因EPERM而失败。
在我就此主题进行的各种搜索中,我发现了应该应用该功能的提示。例如,来自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
不幸的是,这似乎不适用于我的系统。
注意:我正在使用由芯片组供应商修改的系统和内核运行,因此可能会修改某些内容以阻止其工作。
有谁知道
答案 0 :(得分:4)
事实证明,Android修改了内核功能系统,允许根据group-id验证特定功能。不幸的是,所做的修改似乎并未涵盖所有案例。要解决我遇到的问题,我修改了 cap_netlink_recv 检查以使用Android修改后的 cap_capability 调用。这样,net_link组中的用户就可以获得 CAP_NET_LINK 功能。
这一变化似乎符合对Android内核进行修改的精神,并适用于我的情况。
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
答案 1 :(得分:1)
实际上,在netlink路径中,v3.1-18-gfd77846 之前没有检查内核版本的其他权限。
最初完全替换cap_raised
似乎并不是一个好主意,因此我选择在cap_capable
中添加类似的检查。其他可能的cap
是CAP_SYS_ADMIN
,CAP_AUDIT_CONTROL
和CAP_AUDIT_WRITE
,但这些与网络无关。请注意,自上述提交以来,它最终会调用cap_capable
(通过capable
)。
补丁:
diff --git a/security/commoncap.c b/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;
对于那些关注CAP_NET_RAW
的人,您需要加入net_raw
群组。将该组添加到现有android.permission.NET_ADMIN
权限或应用以下框架修补程序:
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" >