system server and mass storage

222 views
Skip to first unread message

Andrew Boie

unread,
Jul 21, 2010, 11:32:04 AM7/21/10
to android-platform
I have some questions about the policy which forbids processes running
as the system server user ID from accessing mass storage. This is
enforced by the file permissions on the sdcard and child directories;
the system_server UID owns them, but has no read/write access.

The rationale I have seen is this:

>>> If you want the system process to do work on the SD card, you will need a
>>>> helper app running as another uid that does this for it. The system user
>>>> is
>>>> not allowed to touch the SD card so that the system does not get killed if
>>>> the card is removed or unmounted.

The problem is that some other applications may need to run as that
UID in order to have other privileges. (i.e. add
android:sharedUserId="android.uid.system" to the manifest). For
example, it's impossible to set native properties or start/stop
services from the Java domain unless you're running as the system
server UID or make modifications to the whitelist of UIDs which can
set properties.

For my particular case, we have some in-house logging and test tools
which are seriously stymied by this policy. There is no serious
consequence if they get unexpectedly killed if the device enters mass
storage mode, but we have to jump through a lot of hoops to be able to
access the sd card and also set properties.

Is the restriction on sd card access supposed to guard against bad
programming practices inside the system_server itself? Why is it
enforced at this level, instead of just telling people who work on
that code "don't access the sdcard"?

Best Regards,
Andrew Boie

Dianne Hackborn

unread,
Jul 21, 2010, 3:07:19 PM7/21/10
to android-...@googlegroups.com
They'll need to run as a different uid.  Note that you can run as any uid you want, still be signed with the platform cert, and thus still be able granted all platform permissions.  On Android the system ui is nearly the same as root, so very very few things should be running as that uid if they aren't actually running in the system process.  (The only other thing I know of is Settings and, really, it would be far preferable that the Settings app not run as the system uid and we should strive towards that.)

The SD access restriction is in place because:

- It is very easy in Java to accidentally hold an open fd for an indeterminate about of time (due to garbage collection etc).
- Stating rules gives no guarantees that code will actually follow them.
- It is extremely hard to verify that code that may open a file on the sd card will actually always manage to close it 
- Getting into a situation where a system has an open SD card while trying to unmount, and doesn't immediately close it, results in a very bad situation: either the unmount takes a possibly infinite amount of time to complete, or the system process must be killed.


--
You received this message because you are subscribed to the Google Groups "android-platform" group.
To post to this group, send email to android-...@googlegroups.com.
To unsubscribe from this group, send email to android-platfo...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-platform?hl=en.




--
Dianne Hackborn
Android framework engineer
hac...@android.com

Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails.  All such questions should be posted on public forums, where I and others can see and answer them.

Andrew Boie

unread,
Jul 26, 2010, 10:03:32 AM7/26/10
to android-platform
On Jul 21, 2:07 pm, Dianne Hackborn <hack...@android.com> wrote:
> They'll need to run as a different uid.  Note that you can run as any uid
> you want, still be signed with the platform cert, and thus still be able
> granted all platform permissions.

Dianne,

Thanks for the clarification. However, I'm looking at the code and I'm
not seeing how I can start/stop services without running as the system
server UID or modifying the framework. It is not sufficient to simply
sign the app with the platform cert.

In system/core/init/property_service.c, the check_control_perms(valud,
uid, gid) gates any attempt to start/stop services. Any process
running as root or system_server is allowed (AID_ROOT and AID_SYSTEM,
respectively). Then the array control_perms is examined; the process
name, and either the UID or GID must match, or an error like this ends
up in dmesg:

init: sys_prop: Unable to start service ctl [sunnyd] uid: 10095 pid:
1681

So it looks like I will have to force my app to run as a specific
predefined UID or GID, and add this to control_perms for this to work
correctly. Do you know of a better way to do this?

Best Regards,
Andrew Boie

Dianne Hackborn

unread,
Jul 26, 2010, 5:17:29 PM7/26/10
to android-...@googlegroups.com
You don't need to do anything with init.  You can make an .apk, sign it with the platform cert, and unless you do something special it will be dynamically assigned its own uid at first system boot.


Best Regards,
Andrew Boie

--
You received this message because you are subscribed to the Google Groups "android-platform" group.
To post to this group, send email to android-...@googlegroups.com.
To unsubscribe from this group, send email to android-platfo...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-platform?hl=en.

Andrew Boie

unread,
Jul 27, 2010, 10:34:28 AM7/27/10
to android-platform
On Jul 26, 4:17 pm, Dianne Hackborn <hack...@android.com> wrote:
> You don't need to do anything with init.  You can make an .apk, sign it with
> the platform cert, and unless you do something special it will be
> dynamically assigned its own uid at first system boot.

Hello Dianne,

I think we are misunderstanding each other. What I am trying to say
that signing with the platform cert is *not sufficient* to allow the
process to start/stop services. Unless I assign my app a static UID
and modify the ACL hard-coded in property_service.c in init, any
attempt to set properties or start/stop services results in init
refusing to do so and logging an error, because of this code which
checks the UID/GID of the process trying to set the ctl.* property:

/*
* White list of UID that are allowed to start/stop services.
* Currently there are no user apps that require.
*/
struct {
const char *service;
unsigned int uid;
unsigned int gid;
} control_perms[] = {
{"kdhcp0", AID_RADIO ,0},
{"kdhcp1", AID_RADIO ,0},
{"kdhcp2", AID_RADIO ,0},
{ "dumpstate",AID_SHELL, AID_LOG },
}

/*
* Checks permissions for starting/stoping system services.
* AID_SYSTEM and AID_ROOT are always allowed.
*
* Returns 1 if uid allowed, 0 otherwise.
*/
static int check_control_perms(const char *name, int uid, int gid) {
int i;
if (uid == AID_SYSTEM || uid == AID_ROOT)
return 1;

/* Search the ACL */
for (i = 0; control_perms[i].service; i++) {
if (strcmp(control_perms[i].service, name) == 0) {
if ((uid && control_perms[i].uid == uid) ||
(gid && control_perms[i].gid == gid)) {
return 1;
}
}
}
return 0;
}


void handle_property_set_fd(int fd)
{
.....
if(memcmp(msg.name,"ctl.",4) == 0) {
if (check_control_perms(msg.value, cr.uid, cr.gid)) {
handle_control_message((char*) msg.name + 4, (char*)
msg.value);
} else {
ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d
pid:%d\n gid:%d\n",
msg.name + 4, msg.value, cr.uid, cr.pid,
cr.gid);
}
...
}

Best Regards
Andrew Boie

Dianne Hackborn

unread,
Jul 27, 2010, 12:31:04 PM7/27/10
to android-...@googlegroups.com
Okay then put your SD card access code in another process as a uid that can do that, and do IPCs with it.

}

Best Regards
Andrew Boie

--
You received this message because you are subscribed to the Google Groups "android-platform" group.
To post to this group, send email to android-...@googlegroups.com.
To unsubscribe from this group, send email to android-platfo...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-platform?hl=en.

Reply all
Reply to author
Forward
0 new messages