什么会导致 socket() “权限被拒绝"错误? [英] what can cause a socket() "Permission denied" error?

查看:19
本文介绍了什么会导致 socket() “权限被拒绝"错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Android 4 下,以下简单的本机 C 代码行失败,并出现 Permission denied 错误 when not run as root:

Under Android 4, the following simple native C code line fails with an Permission denied error when not run as root:

online_socket = socket(AF_INET, SOCK_DGRAM, 0);

确实拥有对设备的 root 访问权限,但希望以非特权用户身份运行该进程.

I do have root access to the device, but want to run the process as non-privileged user.

请注意,该错误甚至在绑定套接字之前就发生了.

Note that the error happens even before binding the socket.

我想有一些安全设置需要调整?谁能告诉我在哪里看?

I guess there is some security setting that needs to be tweaked? Anyone can tell me where to look?

在这种情况下,O/S 确实是 Android,但我想问题确实与 Linux 相关(因为 Android 基于 Linux 内核).

The O/S is really Android in this case, but I guess the problem is really Linux-related (since Android is based on a Linux Kernel).

对于那些想知道的人:这是一个在 Android 4 环境中运行的完整 (debootstrapped) Debian Jessie 安装中运行的自定义程序.

For those wondering: This is a custom program that runs in a full (debootstrapped) Debian Jessie installation running in an Android 4 environment.

我了解到 Android 内核有一个特殊的 CONFIG_ANDROID_PARANOID_NETWORK 扩展,它只允许 AID_INETAID_NET_RAW 组中的用户访问网络.

I've learned that the Android Kernel has a special CONFIG_ANDROID_PARANOID_NETWORK extension that allows network access only to users in AID_INET and AID_NET_RAW groups.

然而,即使在将用户添加到这些组之后,socket() 仍然被拒绝(并且 ping 似乎有同样的问题,顺便说一句).

However, even after adding the user to these groups, socket() is still rejected (and ping appears to have the same problem, BTW).

uid=5(imp) gid=51(imp) groups=51(imp),3003(aid_inet),3004(aid_net_raw),3005(aid_admin),3001(aid_bt),3002(aid_bt_net)

我不知道该特定内核中是否设置了 CONFIG_ANDROID_PARANOID_NETWORK 标志,因为我无权访问配置文件.

I can't tell if that CONFIG_ANDROID_PARANOID_NETWORK flag is set in this particular Kernel, as I don't have access to the config file.

我发现root 以及我的非特权用户imp实际上可以成功调用socket() - 至少使用上述组设置.

I found out that both root and also my unprivileged user imp can in fact successfully call socket() - at least with the groups setup described above.

然而,使用seteuid()系统调用与root相同的进程,然后切换到imp调用阻止 socket() 成功.有什么想法吗?

However, calling the same process as root and then switching to imp using the seteuid() system call prevents socket() from succeeding. Any ideas?

推荐答案

事实证明,Android 使用了一个特殊的内核补丁,该补丁通过 CONFIG_ANDROID_PARANOID_NETWORK 激活.此补丁允许属于具有硬编码 ID 的某些特殊组的系统用户进行网络访问.

As it turns out, Android uses a special Kernel patch that's activated with CONFIG_ANDROID_PARANOID_NETWORK. This patch allows network access to system users that belong to certain special groups with hardcoded IDs.

groupadd -g 3001 aid_bt
groupadd -g 3002 aid_bt_net
groupadd -g 3003 aid_inet
groupadd -g 3004 aid_net_raw
groupadd -g 3005 aid_admin

这是因为 Android 通常仅在特定应用具有网络权限时才会将用户(即应用)添加到这些组中.

That's because Android normally adds users (i.e. apps) to these groups only when the specific app has networking permissions.

将用户添加到这些组中将授予它使用 socket() 的权限,如问题中所述:

Adding a user to these groups gives it permission to use socket() as described in the question:

usermod -a -G aid_bt,aid_bt_net,aid_inet,aid_net_raw,aid_admin someuser

然而,当进程使用 seteuid()root 切换到非特权用户(例如 someusercode>),那么这个有效用户拥有aid_*组成员资格是不够的(或者可能是无关).相反,root 用户必须明确是这些组的成员:

However, when a process uses seteuid() to switch from root to a unprivileged user (for example someuser), then it's not enough (or probably irrelevant) that this effective user has aid_* group membership. Instead, the root user must explicitly be a member of these groups:

usermod -a -G aid_bt,aid_bt_net,aid_inet,aid_net_raw,aid_admin root

这为我解决了问题.

请注意,我也尝试使用 setegid() 和类似的替代方法,但这些都没有帮助...

Note that I've also tried to play with setegid() and similar as an alternative, but none of that helped...

这篇关于什么会导致 socket() “权限被拒绝"错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆