简体   繁体   English

什么可以导致socket()“Permission denied”错误?

[英]what can cause a socket() “Permission denied” error?

Under Android 4, the following simple native C code line fails with an Permission denied error when not run as root : 下的Android 4,以下简单原生的C代码行失败,并Permission denied 运行错误root

online_socket = socket(AF_INET, SOCK_DGRAM, 0);

I do have root access to the device, but want to run the process as non-privileged user. root的设备访问,但要运行的过程,非特权用户。

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? 谁能告诉我在哪里看?

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). 在这种情况下,O / S实际上是Android,但我猜这个问题确实与Linux有关(因为Android基于Linux内核)。

For those wondering: This is a custom program that runs in a full ( debootstrap ped) Debian Jessie installation running in an Android 4 environment. 对于那些想知道:这是一个自定义程序,运行在Android 4环境中运行的完整( debootstrap ped)Debian Jessie安装。

Update 更新

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. 我了解到Android内核有一个特殊的CONFIG_ANDROID_PARANOID_NETWORK扩展,它允许仅对AID_INETAID_NET_RAW组中的用户进行网络访问。

However, even after adding the user to these groups, socket() is still rejected (and ping appears to have the same problem, BTW). 但是,即使将用户添加到这些组后,仍然拒绝socket() (并且ping似乎也有同样的问题,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)

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. 我无法判断是否在此特定内核中设置了CONFIG_ANDROID_PARANOID_NETWORK标志,因为我无权访问配置文件。

Update 2 更新2

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. 我发现root 我的非特权用户imp实际上可以成功调用socket() - 至少使用上面描述的组设置。

However, calling the same process as root and then switching to imp using the seteuid() system call prevents socket() from succeeding. 但是,调用与root相同的进程然后使用seteuid()系统调用切换到imp阻止socket()成功。 Any ideas? 有任何想法吗?

As it turns out, Android uses a special Kernel patch that's activated with CONFIG_ANDROID_PARANOID_NETWORK . 事实证明,Android使用了一个使用CONFIG_ANDROID_PARANOID_NETWORK激活的特殊内核补丁。 This patch allows network access to system users that belong to certain special groups with hardcoded IDs. 此修补程序允许网络访问属于具有硬编码ID的特定特殊组的系统用户。

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

That's because Android normally adds users (ie apps) to these groups only when the specific app has networking permissions. 这是因为Android通常仅在特定应用具有网络权限时才将用户(即应用)添加到这些组。

Adding a user to these groups gives it permission to use socket() as described in the question: 将用户添加到这些组允许它使用socket() ,如问题中所述:

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

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. 但是 ,当进程使用seteuid()root用户切换到非特权用户(例如someuser )时,这个有效用户具有aid_*组成员资格是不够的(或者可能无关紧要 )。 Instead, the root user must explicitly be a member of these groups: 相反, root用户必须明确地是这些组的成员:

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

This solved the problem for me. 这解决了我的问题。

Note that I've also tried to play with setegid() and similar as an alternative, but none of that helped... 请注意,我也尝试使用setegid()和类似的替代方案,但没有一个帮助...

Those who struggle with the apt-get on Android (with the CONFIG_ANDROID_PARANOID_NETWORK enabled which restricts network access to users who are member of specific groups) there are two workaround: 那些在Android上使用apt-get (启用了CONFIG_ANDROID_PARANOID_NETWORK ,限制对特定组成员用户的网络访问)的人有两种解决方法:

  1. groupadd -g 3003 aid_inet && usermod -G nogroup -g aid_inet _apt
  2. echo 'APT::Sandbox::User "root";' > /etc/apt/apt.conf.d/01-android-nosandbox

This is because apt-get is running http/https/gpgv methods under a sandboxed user, which is _apt by default: 这是因为apt-get在沙盒用户下运行http / https / gpgv方法,默认情况下为_apt

root      1465  0.0  0.0  31408  4956 pts/0    S    11:48   0:00  |   |       \_ -bash
root     23814  0.1  0.1  65300 10124 pts/0    T    18:58   0:00  |   |           \_ apt-get update
_apt     23818  0.0  0.1  90208  8852 pts/0    T    18:58   0:00  |   |           |   \_ /usr/lib/apt/methods/http
_apt     23819  0.0  0.1  90208  8828 pts/0    T    18:58   0:00  |   |           |   \_ /usr/lib/apt/methods/https
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM