[Mono-dev] Tweaks needed in security.c for running Mono on Android - patch included

Koushik K. Dutta koush at koushikdutta.com
Sat Jan 10 21:32:45 EST 2009


Hi all, I'm working on getting Mono running under Android. So far, I've been able to get things running with next to no code changes (by way of configure, compiler and linker options).

I did run into one issue though that required a code change. Mono has a dependency on libc.so. On Android, Google implemented a custom lightweight version of libc.so, which they call "Bionic". I have tried building Mono against Bionic, but at the moment, it seems basically impossible because Bionic does not have Unicode support. (I will dig into other solutions for this further, but it's low priority at the moment... I want to get things running :))

So, as a result, Mono on Android needs to be packaged with the standard ARM/Linux version of libc.  However, there are significant differences between the Linux file system and Android file system. So when Mono's uses libc's getpwuid and getpwuid_r, it fails, and causes further problems in the runtime. Linux's getpwuid works by examining various files in /etc. But, Android does not have a /etc. Android has a uid/gid repository that is very different from typical Linux distributions.

For reference, here is Bionic's implementation of getpwuid (there is no getpwuid_r):

struct passwd* getpwuid(uid_t uid)
{
    stubs_state_t*  state = __stubs_state();
    struct passwd*  pw;

    if (state == NULL)
        return NULL;

    pw = &state->passwd;

    if ( android_id_to_passwd(pw, uid) != NULL )
        return pw;

    if (uid < AID_APP) {
        errno = ENOENT;
        return NULL;
    }

    snprintf( state->app_name_buffer, sizeof state->app_name_buffer,
              "app_%d", uid - AID_APP );

    pw->pw_name  = state->app_name_buffer;
    pw->pw_dir   = "/data";
    pw->pw_shell = "/system/bin/sh";
    pw->pw_uid   = uid;
    pw->pw_gid   = uid;

    return pw;
}

getpwuid is used in three locations Mono. The two troublesome ones are in mono/metadata/security.c in the functions "GetTokenName" and "IsMemberOf". (The third is in pwd.c for Mono's Posix syscall wrapper, but that is not causing the problem. I'll fix that later.)

I have attached a patch file that I have successfully built and tested against Android.  It is also regression safe, as all the new code is inside a #ifdef PLATFORM_ANDROID block. The workaround is simple, and there are comments explaining how the Android uid model works.

Alternatively, I can obviously compile a custom version of libc.so for Mono, but I do not think that is a good solution. Mono is already using #ifdef PLATFORM_WIN32 at the same points in code that I placed my PLATFORM_ANDROID, and I'm assuming that the Mono developers will be more open to my proposed changes.

For information about how to build Mono to target Android, you can reference my post: http://www.koushikdutta.com/2009/01/building-mono-for-android.html. Or feel free to contact me.

Thanks,

Koushik Dutta
www.koushikdutta.com<http://www.koushikdutta.com/>



Koushik Dutta
www.koushikdutta.com<http://www.koushikdutta.com/>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20090110/fcd163f2/attachment-0001.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: security.c.patch
Type: application/octet-stream
Size: 1203 bytes
Desc: security.c.patch
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20090110/fcd163f2/attachment-0001.obj 


More information about the Mono-devel-list mailing list