Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
492 views
in Technique[技术] by (71.8m points)

android - 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:

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.

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).

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

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.

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)

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.

Update 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.

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

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

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

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

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...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...