mailing list of musl libc
 help / color / mirror / code / Atom feed
* musl and android
@ 2015-01-15  9:13 Рысь
  2015-01-15 11:01 ` Rich Felker
  2015-01-18  6:32 ` Рысь
  0 siblings, 2 replies; 18+ messages in thread
From: Рысь @ 2015-01-15  9:13 UTC (permalink / raw)
  To: musl

Hello all!

Are there any efforts or even a project which aims to port musl to
android platform?

For a year I slowly had built and running a couple of C tty only
programs such as iptables, tcpdump and of course busybox and many
others including my own with musl libc linked statically. They work
perfectly (no much differences between an ARM phone and, for example,
raspberry pi SoC) but a few items I missed:

+ Proper DNS resolving is not available
+ Translation of android special user names is not done

As an advanced Linux user I know that android is not friendly enough to
plain C stuff and it's libc is even not finished now so I aimed to port
at least listed things to musl.

Because I am not going beyond listed items, a patch can be developed
just to support these inside musl-linked binaries.

I am first here or there is already someone who done this before?


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-15  9:13 musl and android Рысь
@ 2015-01-15 11:01 ` Rich Felker
  2015-01-15 12:00   ` dynamic linking (Re: [musl] musl and android) u-wsnj
  2015-01-15 13:53   ` musl and android Рысь
  2015-01-18  6:32 ` Рысь
  1 sibling, 2 replies; 18+ messages in thread
From: Rich Felker @ 2015-01-15 11:01 UTC (permalink / raw)
  To: musl

On Thu, Jan 15, 2015 at 04:13:22PM +0700, Рысь wrote:
> Hello all!
> 
> Are there any efforts or even a project which aims to port musl to
> android platform?
> 
> For a year I slowly had built and running a couple of C tty only
> programs such as iptables, tcpdump and of course busybox and many
> others including my own with musl libc linked statically. They work
> perfectly (no much differences between an ARM phone and, for example,
> raspberry pi SoC) but a few items I missed:
> 
> + Proper DNS resolving is not available
> + Translation of android special user names is not done
> 
> As an advanced Linux user I know that android is not friendly enough to
> plain C stuff and it's libc is even not finished now so I aimed to port
> at least listed things to musl.
> 
> Because I am not going beyond listed items, a patch can be developed
> just to support these inside musl-linked binaries.
> 
> I am first here or there is already someone who done this before?

Hi,

The above issues are complicated by the fact that musl aims to produce
binaries that work anywhere and that follow existing practice rather
than inventing new mechanisms -- a principle which Android ignored or
even treated with hostility.

Supporting alternate passwd/group backends is an open agenda item, but
the proposed methods we're looking at are still not really "Android
compatible". Same goes for DNS -- the recommended way to do alternate
name resolver backends is a local nameserver, but that's not very
friendly to the Android setup either.

I'm not sure what the best approach here is. Perhaps it's to treat
Android as a new body of existing practice and also support the
gratuitously-different Android things inline in the same binaries.
This seems ugly but perhaps preferable to having multiple incompatible
targets.

For now, the easiest way to deploy musl on Android (by this, I mean as
part of an Android app) seems to be including your own, possibly
patched, copy of the dynamic linker (libc.so/ld-musl) in the package
and executing the program via a wrapper script that manually invokes
the dynamic linker (so the hard-coded PT_INTERP pathname isn't
needed). Or of course static linking works (with similar patching if
necessary). But these are not the approaches I'd like to be
recommending in the long term... :(

Rich


^ permalink raw reply	[flat|nested] 18+ messages in thread

* dynamic linking (Re: [musl] musl and android)
  2015-01-15 11:01 ` Rich Felker
@ 2015-01-15 12:00   ` u-wsnj
  2015-01-15 12:15     ` Rich Felker
  2015-01-15 13:53   ` musl and android Рысь
  1 sibling, 1 reply; 18+ messages in thread
From: u-wsnj @ 2015-01-15 12:00 UTC (permalink / raw)
  To: musl

On Thu, Jan 15, 2015 at 06:01:58AM -0500, Rich Felker wrote:
> copy of the dynamic linker (libc.so/ld-musl) in the package
> and executing the program via a wrapper script that manually invokes
> the dynamic linker (so the hard-coded PT_INTERP pathname isn't
> needed).

> But these are not the approaches I'd like to be
> recommending in the long term... :(

Actually I believe (and know from long time experience) this to be
the only "sane"/robust/general way to run dynamically linked executables.

I don't think that the implications of hardcoding the interpreter
path were well understood when dynamic linking was first deployed,
the hardcoding merely became percepted as the only/natural approach
when the purpose was to cheaply imitate the behaviour of statically
linked programs. (This mimics the #!/... which is similarly
limited/broken. The plain text scripts are though relatively easy
to modify to hack around the limitation, according to local curcumstances)

Rune



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: dynamic linking (Re: [musl] musl and android)
  2015-01-15 12:00   ` dynamic linking (Re: [musl] musl and android) u-wsnj
@ 2015-01-15 12:15     ` Rich Felker
  2015-01-15 13:04       ` u-wsnj
  0 siblings, 1 reply; 18+ messages in thread
From: Rich Felker @ 2015-01-15 12:15 UTC (permalink / raw)
  To: musl

On Thu, Jan 15, 2015 at 01:00:05PM +0100, u-wsnj@aetey.se wrote:
> On Thu, Jan 15, 2015 at 06:01:58AM -0500, Rich Felker wrote:
> > copy of the dynamic linker (libc.so/ld-musl) in the package
> > and executing the program via a wrapper script that manually invokes
> > the dynamic linker (so the hard-coded PT_INTERP pathname isn't
> > needed).
> 
> > But these are not the approaches I'd like to be
> > recommending in the long term... :(
> 
> Actually I believe (and know from long time experience) this to be
> the only "sane"/robust/general way to run dynamically linked executables.

It depends on your perspective. If you're viewing them as
self-contained entities, then yes, but if you're viewing them as
something running in an existing library ecosystem, there's no
problem.

> I don't think that the implications of hardcoding the interpreter
> path were well understood when dynamic linking was first deployed,
> the hardcoding merely became percepted as the only/natural approach
> when the purpose was to cheaply imitate the behaviour of statically
> linked programs. (This mimics the #!/... which is similarly
> limited/broken. The plain text scripts are though relatively easy
> to modify to hack around the limitation, according to local curcumstances)

I think this could be fixed easily by having the kernel support
$ORIGIN in PT_INTERP.

Rich


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: dynamic linking (Re: [musl] musl and android)
  2015-01-15 12:15     ` Rich Felker
@ 2015-01-15 13:04       ` u-wsnj
  2015-01-15 13:34         ` Rich Felker
  0 siblings, 1 reply; 18+ messages in thread
From: u-wsnj @ 2015-01-15 13:04 UTC (permalink / raw)
  To: musl

On Thu, Jan 15, 2015 at 07:15:36AM -0500, Rich Felker wrote:
> > > and executing the program via a wrapper script that manually invokes
> > > the dynamic linker (so the hard-coded PT_INTERP pathname isn't
> > > needed).

> > Actually I believe (and know from long time experience) this to be
> > the only "sane"/robust/general way to run dynamically linked executables.
> 
> It depends on your perspective. If you're viewing them as
> self-contained entities, then yes, but if you're viewing them as
> something running in an existing library ecosystem, there's no
> problem.

Right, it depends. For the second perspective you seem to imply that
an "ecosystem" is to be managed in a certain way.

Binaries belonging to my "library ecosystems" still can be subject to
the C library tests and upgrades on a per-binary basis, not only "all
binaries belonging to the same ecosystem at once", which is of course
possible as well.

This would be impossible if I'd rely on the hardcoded loader path.

> > I don't think that the implications of hardcoding the interpreter
> > path were well understood when dynamic linking was first deployed,
> > the hardcoding merely became percepted as the only/natural approach
> > when the purpose was to cheaply imitate the behaviour of statically
> > linked programs. (This mimics the #!/... which is similarly
> > limited/broken. The plain text scripts are though relatively easy
> > to modify to hack around the limitation, according to local curcumstances)
> 
> I think this could be fixed easily by having the kernel support
> $ORIGIN in PT_INTERP.

Unfortunately, no. $ORIGIN does not and can not replace a run time
choice of the dynamic loader. As a simple example, consider a binary on
a readonly media. How would you convince the kernel to run a different
loader than assumed (among others) by the path to the mount point of
the media? In my eyes the mounting of the media (possibly with lots of
binaries on it) and running a certain loader for a certain binary are
very different things and do not have to / should not depend on each other.

Rune



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: dynamic linking (Re: [musl] musl and android)
  2015-01-15 13:04       ` u-wsnj
@ 2015-01-15 13:34         ` Rich Felker
  2015-01-15 15:56           ` OT: " u-wsnj
  0 siblings, 1 reply; 18+ messages in thread
From: Rich Felker @ 2015-01-15 13:34 UTC (permalink / raw)
  To: musl

On Thu, Jan 15, 2015 at 02:04:32PM +0100, u-wsnj@aetey.se wrote:
> On Thu, Jan 15, 2015 at 07:15:36AM -0500, Rich Felker wrote:
> > > > and executing the program via a wrapper script that manually invokes
> > > > the dynamic linker (so the hard-coded PT_INTERP pathname isn't
> > > > needed).
> 
> > > Actually I believe (and know from long time experience) this to be
> > > the only "sane"/robust/general way to run dynamically linked executables.
> > 
> > It depends on your perspective. If you're viewing them as
> > self-contained entities, then yes, but if you're viewing them as
> > something running in an existing library ecosystem, there's no
> > problem.
> 
> Right, it depends. For the second perspective you seem to imply that
> an "ecosystem" is to be managed in a certain way.
> 
> Binaries belonging to my "library ecosystems" still can be subject to
> the C library tests and upgrades on a per-binary basis, not only "all
> binaries belonging to the same ecosystem at once", which is of course
> possible as well.
> 
> This would be impossible if I'd rely on the hardcoded loader path.

That's why I said i depends on your perspective. From your perspective
this does not work. From most traditional distributions' perspectives,
it does.

> > > I don't think that the implications of hardcoding the interpreter
> > > path were well understood when dynamic linking was first deployed,
> > > the hardcoding merely became percepted as the only/natural approach
> > > when the purpose was to cheaply imitate the behaviour of statically
> > > linked programs. (This mimics the #!/... which is similarly
> > > limited/broken. The plain text scripts are though relatively easy
> > > to modify to hack around the limitation, according to local curcumstances)
> > 
> > I think this could be fixed easily by having the kernel support
> > $ORIGIN in PT_INTERP.
> 
> Unfortunately, no. $ORIGIN does not and can not replace a run time
> choice of the dynamic loader. As a simple example, consider a binary on
> a readonly media. How would you convince the kernel to run a different
> loader than assumed (among others) by the path to the mount point of
> the media? In my eyes the mounting of the media (possibly with lots of
> binaries on it) and running a certain loader for a certain binary are
> very different things and do not have to / should not depend on each other.

If you're distributing the binary and dynamic loader/libc and all
libraries it needs together, I'd assume they'd all be in the same
directory, or else in ../lib/ relative to the binary. In that case
$ORIGIN works perfectly fine. Note that $ORIGIN is _not_ an
environment variable; it's a dynamic-linker feature for locating
libraries relative to the ELF file (main executable or other library)
that needs (via DT_NEEDED) them, and the same concept would work for
PT_INTERP.

Rich


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-15 11:01 ` Rich Felker
  2015-01-15 12:00   ` dynamic linking (Re: [musl] musl and android) u-wsnj
@ 2015-01-15 13:53   ` Рысь
  1 sibling, 0 replies; 18+ messages in thread
From: Рысь @ 2015-01-15 13:53 UTC (permalink / raw)
  To: musl

В Thu, 15 Jan 2015 06:01:58 -0500
Rich Felker <dalias@libc.org> пишет:

> On Thu, Jan 15, 2015 at 04:13:22PM +0700, Рысь wrote:
> > Hello all!
> > 
> > Are there any efforts or even a project which aims to port musl to
> > android platform?
> > 
> > For a year I slowly had built and running a couple of C tty only
> > programs such as iptables, tcpdump and of course busybox and many
> > others including my own with musl libc linked statically. They work
> > perfectly (no much differences between an ARM phone and, for
> > example, raspberry pi SoC) but a few items I missed:
> > 
> > + Proper DNS resolving is not available
> > + Translation of android special user names is not done
> > 
> > As an advanced Linux user I know that android is not friendly
> > enough to plain C stuff and it's libc is even not finished now so I
> > aimed to port at least listed things to musl.
> > 
> > Because I am not going beyond listed items, a patch can be developed
> > just to support these inside musl-linked binaries.
> > 
> > I am first here or there is already someone who done this before?
> 
> Hi,
> 
> The above issues are complicated by the fact that musl aims to produce
> binaries that work anywhere and that follow existing practice rather
> than inventing new mechanisms -- a principle which Android ignored or
> even treated with hostility.

As for now, I do not aim to make portable binaries since I do not
redistribute them (okay, I distribute them to my friends. Does that
count?)

> Supporting alternate passwd/group backends is an open agenda item, but
> the proposed methods we're looking at are still not really "Android
> compatible". Same goes for DNS -- the recommended way to do alternate
> name resolver backends is a local nameserver, but that's not very
> friendly to the Android setup either.

Do not forget about timezones in android (I forgot to mention that -
sorry)

> 
> I'm not sure what the best approach here is. Perhaps it's to treat
> Android as a new body of existing practice and also support the
> gratuitously-different Android things inline in the same binaries.
> This seems ugly but perhaps preferable to having multiple incompatible
> targets.
> 
> For now, the easiest way to deploy musl on Android (by this, I mean as
> part of an Android app) seems to be including your own, possibly
> patched, copy of the dynamic linker (libc.so/ld-musl) in the package
> and executing the program via a wrapper script that manually invokes
> the dynamic linker (so the hard-coded PT_INTERP pathname isn't
> needed). Or of course static linking works (with similar patching if
> necessary). But these are not the approaches I'd like to be
> recommending in the long term... :(
> 
> Rich

No I am not using musl as a part of android app. I use musl in low
level C programs (relative to Java user apps) such as busybox, strace,
tcpdump, iptables, iproute2... That's why I do seek for a quick
solution now.

Android is not friendly at all, but I need to do something with it. I
want musl on it working fine, because I do want get rid of ugly android
development toolchain and it's partial libc. I completely tired of that
environment.

So, if there are no any other attempts, I can try?

Thanks.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* OT: Re: dynamic linking (Re: [musl] musl and android)
  2015-01-15 13:34         ` Rich Felker
@ 2015-01-15 15:56           ` u-wsnj
  0 siblings, 0 replies; 18+ messages in thread
From: u-wsnj @ 2015-01-15 15:56 UTC (permalink / raw)
  To: musl

Actually I do not suggest any change, musl suits my usage model well
(kudos for the support of running the loader explicitly)!

On Thu, Jan 15, 2015 at 08:34:45AM -0500, Rich Felker wrote:
> That's why I said i depends on your perspective. From your perspective
> this does not work. From most traditional distributions' perspectives,
> it does.

Well said.

The traditional distributions choose to live with the far reaching
consequences of their technical choices. I argue that some constraints
(iow sacrifices) are not necessary and only exist as a consequence
of the unfortunate choices.

> > Unfortunately, no. $ORIGIN does not and can not replace a run time
> > choice of the dynamic loader.

> If you're distributing the binary and dynamic loader/libc and all
> libraries it needs together, I'd assume they'd all be in the same
> directory, or else in ../lib/ relative to the binary. In that case

You suggest a somewhat more relaxed set of assumptions than the
traditional ones. Yes this would be useful, but unfortunately still
setting some more or less arbitrary boundaries.

> $ORIGIN works perfectly fine. Note that $ORIGIN is _not_ an
> environment variable; it's a dynamic-linker feature for locating
> libraries relative to the ELF file (main executable or other library)
> that needs (via DT_NEEDED) them, and the same concept would work for
> PT_INTERP.

Indeed, good to point this out for a casual reader.

Using an environment variable would be otherwise a quite general solution
but I guess this would be very hard to convince the kernel developers to
implement (presumably hardly possible to implement without redesigning
the kernel security model).

Regards,
Rune



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-15  9:13 musl and android Рысь
  2015-01-15 11:01 ` Rich Felker
@ 2015-01-18  6:32 ` Рысь
  2015-01-18  6:44   ` Rich Felker
  1 sibling, 1 reply; 18+ messages in thread
From: Рысь @ 2015-01-18  6:32 UTC (permalink / raw)
  To: musl

В Thu, 15 Jan 2015 16:13:22 +0700
Рысь <lynx@sibserver.ru> пишет:

> Hello all!
> 
> Are there any efforts or even a project which aims to port musl to
> android platform?
> 
> For a year I slowly had built and running a couple of C tty only
> programs such as iptables, tcpdump and of course busybox and many
> others including my own with musl libc linked statically. They work
> perfectly (no much differences between an ARM phone and, for example,
> raspberry pi SoC) but a few items I missed:
> 
> + Proper DNS resolving is not available
> + Translation of android special user names is not done
> 
> As an advanced Linux user I know that android is not friendly enough
> to plain C stuff and it's libc is even not finished now so I aimed to
> port at least listed things to musl.
> 
> Because I am not going beyond listed items, a patch can be developed
> just to support these inside musl-linked binaries.
> 
> I am first here or there is already someone who done this before?

I made a patch to implement all three things for musl on android.

I do not post it here as attachment to this mail because it normally
should not be integrated with musl. The patch itself is here:
http://lynxlynx.tk/prg/patches/musl-1.1.4_android.patch, notes about
it: http://lynxlynx.tk/eng/musl_android/.

Patch is invasive enough I think and not optimized and I agree with Rich
that it must go as a special treat. I tried however move away all
translating code to src/android and headers to include/android.

Patch is still in it's alpha stage, and probably will be changed often.

Modifications made for musl 1.1.4.

If anyone interested to audit it - welcome!


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-18  6:32 ` Рысь
@ 2015-01-18  6:44   ` Rich Felker
  2015-01-18  8:01     ` Рысь
  0 siblings, 1 reply; 18+ messages in thread
From: Rich Felker @ 2015-01-18  6:44 UTC (permalink / raw)
  To: musl

On Sun, Jan 18, 2015 at 01:32:37PM +0700, Рысь wrote:
> В Thu, 15 Jan 2015 16:13:22 +0700
> Рысь <lynx@sibserver.ru> пишет:
> 
> > Hello all!
> > 
> > Are there any efforts or even a project which aims to port musl to
> > android platform?
> > 
> > For a year I slowly had built and running a couple of C tty only
> > programs such as iptables, tcpdump and of course busybox and many
> > others including my own with musl libc linked statically. They work
> > perfectly (no much differences between an ARM phone and, for example,
> > raspberry pi SoC) but a few items I missed:
> > 
> > + Proper DNS resolving is not available
> > + Translation of android special user names is not done
> > 
> > As an advanced Linux user I know that android is not friendly enough
> > to plain C stuff and it's libc is even not finished now so I aimed to
> > port at least listed things to musl.
> > 
> > Because I am not going beyond listed items, a patch can be developed
> > just to support these inside musl-linked binaries.
> > 
> > I am first here or there is already someone who done this before?
> 
> I made a patch to implement all three things for musl on android.
> 
> I do not post it here as attachment to this mail because it normally
> should not be integrated with musl. The patch itself is here:
> http://lynxlynx.tk/prg/patches/musl-1.1.4_android.patch, notes about
> it: http://lynxlynx.tk/eng/musl_android/.
> 
> Patch is invasive enough I think and not optimized and I agree with Rich
> that it must go as a special treat. I tried however move away all
> translating code to src/android and headers to include/android.
> 
> Patch is still in it's alpha stage, and probably will be changed often.
> 
> Modifications made for musl 1.1.4.
> 
> If anyone interested to audit it - welcome!

Thanks. If nothing else, this is very informative as to how Android
does things. I noticed a couple things that could be a lot less
invasive, I think, particularly the builtin users/groups. Couldn't you
just fmemopen() a constant string inside libc in place of /etc/passwd
or /etc/group and use the existing code to parse it?

One thing I noticed -- you seem to have some memory leaks in the code
that produces the passwd/group output -- it's malloc'ing space for
names each time and I don't see anywhere it gets freed. Maybe I'm
missing something though; I just read it briefly.

Another general question I have is why can't the /system issue be
fixed? Is there any good reason Android doesn't have symlinks like
/bin->/system/bin, /etc->/system/etc, /lib->/system/lib,
/tmp->/data/tmp, etc.? The gratuitous incompatibility is really
disgusting.

Rich


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-18  6:44   ` Rich Felker
@ 2015-01-18  8:01     ` Рысь
  2015-01-18 16:40       ` Rich Felker
  0 siblings, 1 reply; 18+ messages in thread
From: Рысь @ 2015-01-18  8:01 UTC (permalink / raw)
  To: musl

В Sun, 18 Jan 2015 01:44:40 -0500
Rich Felker <dalias@libc.org> пишет:

> On Sun, Jan 18, 2015 at 01:32:37PM +0700, Рысь wrote:
> > В Thu, 15 Jan 2015 16:13:22 +0700
> > Рысь <lynx@sibserver.ru> пишет:
> > 
> > > Hello all!
> > > 
> > > Are there any efforts or even a project which aims to port musl to
> > > android platform?
> > > 
> > > For a year I slowly had built and running a couple of C tty only
> > > programs such as iptables, tcpdump and of course busybox and many
> > > others including my own with musl libc linked statically. They
> > > work perfectly (no much differences between an ARM phone and, for
> > > example, raspberry pi SoC) but a few items I missed:
> > > 
> > > + Proper DNS resolving is not available
> > > + Translation of android special user names is not done
> > > 
> > > As an advanced Linux user I know that android is not friendly
> > > enough to plain C stuff and it's libc is even not finished now so
> > > I aimed to port at least listed things to musl.
> > > 
> > > Because I am not going beyond listed items, a patch can be
> > > developed just to support these inside musl-linked binaries.
> > > 
> > > I am first here or there is already someone who done this before?
> > 
> > I made a patch to implement all three things for musl on android.
> > 
> > I do not post it here as attachment to this mail because it normally
> > should not be integrated with musl. The patch itself is here:
> > http://lynxlynx.tk/prg/patches/musl-1.1.4_android.patch, notes about
> > it: http://lynxlynx.tk/eng/musl_android/.
> > 
> > Patch is invasive enough I think and not optimized and I agree with
> > Rich that it must go as a special treat. I tried however move away
> > all translating code to src/android and headers to include/android.
> > 
> > Patch is still in it's alpha stage, and probably will be changed
> > often.
> > 
> > Modifications made for musl 1.1.4.
> > 
> > If anyone interested to audit it - welcome!
> 
> Thanks. If nothing else, this is very informative as to how Android
> does things. I noticed a couple things that could be a lot less
> invasive, I think, particularly the builtin users/groups. Couldn't you
> just fmemopen() a constant string inside libc in place of /etc/passwd
> or /etc/group and use the existing code to parse it?

This sounds more interesting idea, I forgot that get*ent() open fd and
there is fmemopen() function. But app_/ux_ax names still need a
dedicated translation function, probably the same code which will form
a passwd-like string and feed it into get*ent().

> 
> One thing I noticed -- you seem to have some memory leaks in the code
> that produces the passwd/group output -- it's malloc'ing space for
> names each time and I don't see anywhere it gets freed. Maybe I'm
> missing something though; I just read it briefly.

Yes the patch is alpha and the reason why there is so much code is that
I did not know how get*ent() were implemented in musl from beginning,
and learned them only when translation code was ready. This patch is
just to show how a translation layer can be implemented on musl to
(completely) port it to android, and I am probably going to completely
rewrite uid/name translation code based on your suggestion in next days
(or at least try to). Memory leaks are expected now :(

> 
> Another general question I have is why can't the /system issue be
> fixed? Is there any good reason Android doesn't have symlinks like
> /bin->/system/bin, /etc->/system/etc, /lib->/system/lib,
> /tmp->/data/tmp, etc.? The gratuitous incompatibility is really
> disgusting.

First, android has /etc -> /system/etc in place, but, unfortunately, no
more :(

I made /etc -> /system/etc change just because I distrust symlinks when
doing security things. It is usually stable across devices, but it's
just symlink.

It even does not have usual Unix /tmp directory or it's surrogate
somewhere in filesystem. /data/tmp is my adoption, though it's
non-standard on android.

Second, android has a very different bootup process, and all those
links in / are created during bootup (on a tmpfs?). Sadly only /etc is
defined by android developers to be symlink to /system/etc.

Third, there are probably many differences between many android device
vendors, android OS types (different android versions including ancient
ones, different android forks that exist today, vendor customisations
of fs layout and in future many others). In fact, android is _very_
fragmented OS.

All this is based on my experience with some android devices I working
(and worked) with.

> 
> Rich

Your additional input on this will be welcome, thanks!


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-18  8:01     ` Рысь
@ 2015-01-18 16:40       ` Rich Felker
  2015-01-19 18:00         ` Рысь
  2015-01-21 10:34         ` Рысь
  0 siblings, 2 replies; 18+ messages in thread
From: Rich Felker @ 2015-01-18 16:40 UTC (permalink / raw)
  To: musl

On Sun, Jan 18, 2015 at 03:01:19PM +0700, Рысь wrote:
> В Sun, 18 Jan 2015 01:44:40 -0500
> Rich Felker <dalias@libc.org> пишет:
> 
> > On Sun, Jan 18, 2015 at 01:32:37PM +0700, Рысь wrote:
> > > В Thu, 15 Jan 2015 16:13:22 +0700
> > > Рысь <lynx@sibserver.ru> пишет:
> > > 
> > > > Hello all!
> > > > 
> > > > Are there any efforts or even a project which aims to port musl to
> > > > android platform?
> > > > 
> > > > For a year I slowly had built and running a couple of C tty only
> > > > programs such as iptables, tcpdump and of course busybox and many
> > > > others including my own with musl libc linked statically. They
> > > > work perfectly (no much differences between an ARM phone and, for
> > > > example, raspberry pi SoC) but a few items I missed:
> > > > 
> > > > + Proper DNS resolving is not available
> > > > + Translation of android special user names is not done
> > > > 
> > > > As an advanced Linux user I know that android is not friendly
> > > > enough to plain C stuff and it's libc is even not finished now so
> > > > I aimed to port at least listed things to musl.
> > > > 
> > > > Because I am not going beyond listed items, a patch can be
> > > > developed just to support these inside musl-linked binaries.
> > > > 
> > > > I am first here or there is already someone who done this before?
> > > 
> > > I made a patch to implement all three things for musl on android.
> > > 
> > > I do not post it here as attachment to this mail because it normally
> > > should not be integrated with musl. The patch itself is here:
> > > http://lynxlynx.tk/prg/patches/musl-1.1.4_android.patch, notes about
> > > it: http://lynxlynx.tk/eng/musl_android/.
> > > 
> > > Patch is invasive enough I think and not optimized and I agree with
> > > Rich that it must go as a special treat. I tried however move away
> > > all translating code to src/android and headers to include/android.
> > > 
> > > Patch is still in it's alpha stage, and probably will be changed
> > > often.
> > > 
> > > Modifications made for musl 1.1.4.
> > > 
> > > If anyone interested to audit it - welcome!
> > 
> > Thanks. If nothing else, this is very informative as to how Android
> > does things. I noticed a couple things that could be a lot less
> > invasive, I think, particularly the builtin users/groups. Couldn't you
> > just fmemopen() a constant string inside libc in place of /etc/passwd
> > or /etc/group and use the existing code to parse it?
> 
> This sounds more interesting idea, I forgot that get*ent() open fd and
> there is fmemopen() function. But app_/ux_ax names still need a
> dedicated translation function, probably the same code which will form
> a passwd-like string and feed it into get*ent().

The intent is that get{gr,pw}{nam,uid} will eventually support
alternate backends via sending a request and receiving a response in
passwd/group line format. On normal systems this would take place via
a unix socket in some reasonable standard directory, but for Android
you could in principle build a reply mechanism into the binary in
place of it. Note that this would probably not support get{pw,gr}ent
enumeration, but I don't see that as a problem. Traditionally
enumeration does not work with backends like nis or ldap, as far as I
know, and it would be an unreasonable/abusive idiom on such large user
databases.

> > Another general question I have is why can't the /system issue be
> > fixed? Is there any good reason Android doesn't have symlinks like
> > /bin->/system/bin, /etc->/system/etc, /lib->/system/lib,
> > /tmp->/data/tmp, etc.? The gratuitous incompatibility is really
> > disgusting.
> 
> First, android has /etc -> /system/etc in place, but, unfortunately, no
> more :(
> 
> I made /etc -> /system/etc change just because I distrust symlinks when
> doing security things. It is usually stable across devices, but it's
> just symlink.
> 
> It even does not have usual Unix /tmp directory or it's surrogate
> somewhere in filesystem. /data/tmp is my adoption, though it's
> non-standard on android.
> 
> Second, android has a very different bootup process, and all those
> links in / are created during bootup (on a tmpfs?). Sadly only /etc is
> defined by android developers to be symlink to /system/etc.
> 
> Third, there are probably many differences between many android device
> vendors, android OS types (different android versions including ancient
> ones, different android forks that exist today, vendor customisations
> of fs layout and in future many others). In fact, android is _very_
> fragmented OS.
> 
> All this is based on my experience with some android devices I working
> (and worked) with.

If / is a tmpfs, I don't see why proper symlinks can't be created, or
why /tmp can't just be created as a directory on / or as another tmpfs
mount on /tmp. Obviously you can't do these kinds of things as a
normal application installing on Android, but if you're doing your own
system programming on Android or if you have root, this seems like the
obvious correct fix...

I'd really like to hear from the Android side what their motive is for
breaking this by not providing the proper symlinks.

Rich


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-18 16:40       ` Rich Felker
@ 2015-01-19 18:00         ` Рысь
  2015-01-21 10:34         ` Рысь
  1 sibling, 0 replies; 18+ messages in thread
From: Рысь @ 2015-01-19 18:00 UTC (permalink / raw)
  To: musl

В Sun, 18 Jan 2015 11:40:10 -0500
Rich Felker <dalias@libc.org> пишет:

> On Sun, Jan 18, 2015 at 03:01:19PM +0700, Рысь wrote:
> > В Sun, 18 Jan 2015 01:44:40 -0500
> > Rich Felker <dalias@libc.org> пишет:
> > 
> > > On Sun, Jan 18, 2015 at 01:32:37PM +0700, Рысь wrote:
> > > > В Thu, 15 Jan 2015 16:13:22 +0700
> > > > Рысь <lynx@sibserver.ru> пишет:
> > > > 
> > > > > Hello all!
> > > > > 
> > > > > Are there any efforts or even a project which aims to port
> > > > > musl to android platform?
> > > > > 
> > > > > For a year I slowly had built and running a couple of C tty
> > > > > only programs such as iptables, tcpdump and of course busybox
> > > > > and many others including my own with musl libc linked
> > > > > statically. They work perfectly (no much differences between
> > > > > an ARM phone and, for example, raspberry pi SoC) but a few
> > > > > items I missed:
> > > > > 
> > > > > + Proper DNS resolving is not available
> > > > > + Translation of android special user names is not done
> > > > > 
> > > > > As an advanced Linux user I know that android is not friendly
> > > > > enough to plain C stuff and it's libc is even not finished
> > > > > now so I aimed to port at least listed things to musl.
> > > > > 
> > > > > Because I am not going beyond listed items, a patch can be
> > > > > developed just to support these inside musl-linked binaries.
> > > > > 
> > > > > I am first here or there is already someone who done this
> > > > > before?
> > > > 
> > > > I made a patch to implement all three things for musl on
> > > > android.
> > > > 
> > > > I do not post it here as attachment to this mail because it
> > > > normally should not be integrated with musl. The patch itself
> > > > is here:
> > > > http://lynxlynx.tk/prg/patches/musl-1.1.4_android.patch, notes
> > > > about it: http://lynxlynx.tk/eng/musl_android/.
> > > > 
> > > > Patch is invasive enough I think and not optimized and I agree
> > > > with Rich that it must go as a special treat. I tried however
> > > > move away all translating code to src/android and headers to
> > > > include/android.
> > > > 
> > > > Patch is still in it's alpha stage, and probably will be changed
> > > > often.
> > > > 
> > > > Modifications made for musl 1.1.4.
> > > > 
> > > > If anyone interested to audit it - welcome!
> > > 
> > > Thanks. If nothing else, this is very informative as to how
> > > Android does things. I noticed a couple things that could be a
> > > lot less invasive, I think, particularly the builtin
> > > users/groups. Couldn't you just fmemopen() a constant string
> > > inside libc in place of /etc/passwd or /etc/group and use the
> > > existing code to parse it?
> > 
> > This sounds more interesting idea, I forgot that get*ent() open fd
> > and there is fmemopen() function. But app_/ux_ax names still need a
> > dedicated translation function, probably the same code which will
> > form a passwd-like string and feed it into get*ent().
> 
> The intent is that get{gr,pw}{nam,uid} will eventually support
> alternate backends via sending a request and receiving a response in
> passwd/group line format. On normal systems this would take place via
> a unix socket in some reasonable standard directory, but for Android
> you could in principle build a reply mechanism into the binary in
> place of it. Note that this would probably not support get{pw,gr}ent
> enumeration, but I don't see that as a problem. Traditionally
> enumeration does not work with backends like nis or ldap, as far as I
> know, and it would be an unreasonable/abusive idiom on such large user
> databases.
> 
> > > Another general question I have is why can't the /system issue be
> > > fixed? Is there any good reason Android doesn't have symlinks like
> > > /bin->/system/bin, /etc->/system/etc, /lib->/system/lib,
> > > /tmp->/data/tmp, etc.? The gratuitous incompatibility is really
> > > disgusting.
> > 
> > First, android has /etc -> /system/etc in place, but,
> > unfortunately, no more :(
> > 
> > I made /etc -> /system/etc change just because I distrust symlinks
> > when doing security things. It is usually stable across devices,
> > but it's just symlink.
> > 
> > It even does not have usual Unix /tmp directory or it's surrogate
> > somewhere in filesystem. /data/tmp is my adoption, though it's
> > non-standard on android.
> > 
> > Second, android has a very different bootup process, and all those
> > links in / are created during bootup (on a tmpfs?). Sadly only /etc
> > is defined by android developers to be symlink to /system/etc.
> > 
> > Third, there are probably many differences between many android
> > device vendors, android OS types (different android versions
> > including ancient ones, different android forks that exist today,
> > vendor customisations of fs layout and in future many others). In
> > fact, android is _very_ fragmented OS.
> > 
> > All this is based on my experience with some android devices I
> > working (and worked) with.
> 
> If / is a tmpfs, I don't see why proper symlinks can't be created, or
> why /tmp can't just be created as a directory on / or as another tmpfs
> mount on /tmp. Obviously you can't do these kinds of things as a
> normal application installing on Android, but if you're doing your own
> system programming on Android or if you have root, this seems like the
> obvious correct fix...
> 
> I'd really like to hear from the Android side what their motive is for
> breaking this by not providing the proper symlinks.
> 
> Rich

I talked about android as by default an unprivileged user, i.e. most
android devices are shipped so that owner of device cannot modify
certain firmware parts and cannot get root privilege.

Android developers decided to hide script that creates such a layout
into initramfs which is hard to modify on most devices (certain vendor
customisations apply, most do that via undescribed proprietary boot
formats which are flashed directly onto boot partition). Of course an
ordinary user is waaay far away from a right to modify it without dirty
hacks, and / tmpfs has permissions not to create any inodes by
unprivileged users and in fact is mounted readonly.

The "correct fix" is another hardish thing: every such device must be
hacked, and there must be a point from where you can start your own
rc.local. initramfs is not a friend, and on most devices rooted with
supersu (a common proprietary su(1) variant for android with graphical
asking interface) there is /system/etc/install-recovery.sh from where
you can invoke (or even have it as symlink) your rc.local. It's not
portable though (I had seen device which cannot be rooted at all
because vendor locked bootloader completely, or devices which are not
reacted on this file presence in any form)

------------

I still see android issue as a separate one, so patch code in _any_ form
must not go into main musl. If it go, then you must detect somehow are
you running on android or on regular system. One possible way I'm
seeing now is that environment variable ANDROID_PROPERTY_WORKSPACE,
it's presence is that you're likely on android. In any other things,
android is very fragmented. And there is another completely unrelated
code for any normal systems, like this code querying mmaped file.

I think this code or even whole musl should be ported to android as a
separate project, or even musl should replace bionic in future android
(or at least in it's forks). Reason is that android changes are too
invasive.

This is output of "ls -la /" from CyanogenMod 10.1 (no much
differences from original android):

# ls -la /
drwxr-xr-x root     root              2015-01-15 02:08 acct
drwxrwx--x system   cache             2013-09-27 15:00 cache
-rwxr-x--- root     root       268176 1970-01-01 07:00 charger
dr-x------ root     root              2015-01-15 02:08 config
lrwxrwxrwx root     root              2015-01-15 02:08 d -> /sys/kernel/debug
drwxrwx--x system   system            2014-11-12 14:20 data
-rw-r--r-- root     root          136 1970-01-01 07:00 default.prop
drwxr-xr-x root     root              2015-01-15 02:08 dev
drwxrwxr-x radio    system            2013-01-08 22:44 efs
lrwxrwxrwx root     root              2015-01-15 02:08 etc -> /system/etc
lrwxrwxrwx root     root              2015-01-15 02:08 extSdCard -> /storage/sdcard1
-rw-r----- root     root         1178 1970-01-01 07:00 fstab.espresso10
-rwxr-x--- root     root       113592 1970-01-01 07:00 init
-rwxr-x--- root     root         1288 1970-01-01 07:00 init.cm.rc
-rwxr-x--- root     root        13512 1970-01-01 07:00 init.espresso10.rc
-rwxr-x--- root     root         3570 1970-01-01 07:00 init.espresso10.usb.rc
-rwxr-x--- root     root         2770 1970-01-01 07:00 init.goldfish.rc
-rwxr-x--- root     root        21827 1970-01-01 07:00 init.rc
-rwxr-x--- root     root          301 1970-01-01 07:00 init.superuser.rc
-rwxr-x--- root     root         1795 1970-01-01 07:00 init.trace.rc
-rwxr-x--- root     root         3947 1970-01-01 07:00 init.usb.rc
drwxrwxr-x root     system            2015-01-15 02:08 mnt
dr-xr-xr-x root     root              1970-01-01 07:00 proc
drwxr-xr-x root     root              1970-01-01 07:00 res
drwx------ root     root              2013-09-24 09:37 root
drwxr-x--- root     root              1970-01-01 07:00 sbin
lrwxrwxrwx root     root              2015-01-15 02:08 sdcard -> /storage/emulated/legacy
dr-xr-x--- system   sdcard_r          2015-01-15 02:08 storage
drwxr-xr-x root     root              2015-01-15 02:08 sys
drwxr-xr-x root     root              2014-02-20 09:47 system
-rw-r--r-- root     root         1993 1970-01-01 07:00 ueventd.espresso10.rc
-rw-r--r-- root     root          272 1970-01-01 07:00 ueventd.goldfish.rc
-rw-r--r-- root     root         5897 1970-01-01 07:00 ueventd.rc
lrwxrwxrwx root     root              2015-01-15 02:08 usbdisk0 -> /storage/usbdisk0
lrwxrwxrwx root     root              2015-01-15 02:08 vendor -> /system/vendor

Note files with epoch time - they're copied into this space when system
boots.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-18 16:40       ` Rich Felker
  2015-01-19 18:00         ` Рысь
@ 2015-01-21 10:34         ` Рысь
  2015-01-21 18:36           ` Rich Felker
  1 sibling, 1 reply; 18+ messages in thread
From: Рысь @ 2015-01-21 10:34 UTC (permalink / raw)
  To: musl

В Sun, 18 Jan 2015 11:40:10 -0500
Rich Felker <dalias@libc.org> пишет:

> On Sun, Jan 18, 2015 at 03:01:19PM +0700, Рысь wrote:
> > В Sun, 18 Jan 2015 01:44:40 -0500
> > Rich Felker <dalias@libc.org> пишет:
> > 
> > > On Sun, Jan 18, 2015 at 01:32:37PM +0700, Рысь wrote:
> > > > В Thu, 15 Jan 2015 16:13:22 +0700
> > > > Рысь <lynx@sibserver.ru> пишет:
> > > > 
> > > > > Hello all!
> > > > > 
> > > > > Are there any efforts or even a project which aims to port
> > > > > musl to android platform?
> > > > > 
> > > > > For a year I slowly had built and running a couple of C tty
> > > > > only programs such as iptables, tcpdump and of course busybox
> > > > > and many others including my own with musl libc linked
> > > > > statically. They work perfectly (no much differences between
> > > > > an ARM phone and, for example, raspberry pi SoC) but a few
> > > > > items I missed:
> > > > > 
> > > > > + Proper DNS resolving is not available
> > > > > + Translation of android special user names is not done
> > > > > 
> > > > > As an advanced Linux user I know that android is not friendly
> > > > > enough to plain C stuff and it's libc is even not finished
> > > > > now so I aimed to port at least listed things to musl.
> > > > > 
> > > > > Because I am not going beyond listed items, a patch can be
> > > > > developed just to support these inside musl-linked binaries.
> > > > > 
> > > > > I am first here or there is already someone who done this
> > > > > before?
> > > > 
> > > > I made a patch to implement all three things for musl on
> > > > android.
> > > > 
> > > > I do not post it here as attachment to this mail because it
> > > > normally should not be integrated with musl. The patch itself
> > > > is here:
> > > > http://lynxlynx.tk/prg/patches/musl-1.1.4_android.patch, notes
> > > > about it: http://lynxlynx.tk/eng/musl_android/.
> > > > 
> > > > Patch is invasive enough I think and not optimized and I agree
> > > > with Rich that it must go as a special treat. I tried however
> > > > move away all translating code to src/android and headers to
> > > > include/android.
> > > > 
> > > > Patch is still in it's alpha stage, and probably will be changed
> > > > often.
> > > > 
> > > > Modifications made for musl 1.1.4.
> > > > 
> > > > If anyone interested to audit it - welcome!
> > > 
> > > Thanks. If nothing else, this is very informative as to how
> > > Android does things. I noticed a couple things that could be a
> > > lot less invasive, I think, particularly the builtin
> > > users/groups. Couldn't you just fmemopen() a constant string
> > > inside libc in place of /etc/passwd or /etc/group and use the
> > > existing code to parse it?
> > 
> > This sounds more interesting idea, I forgot that get*ent() open fd
> > and there is fmemopen() function. But app_/ux_ax names still need a
> > dedicated translation function, probably the same code which will
> > form a passwd-like string and feed it into get*ent().
> 
> The intent is that get{gr,pw}{nam,uid} will eventually support
> alternate backends via sending a request and receiving a response in
> passwd/group line format. On normal systems this would take place via
> a unix socket in some reasonable standard directory, but for Android
> you could in principle build a reply mechanism into the binary in
> place of it. Note that this would probably not support get{pw,gr}ent
> enumeration, but I don't see that as a problem. Traditionally
> enumeration does not work with backends like nis or ldap, as far as I
> know, and it would be an unreasonable/abusive idiom on such large user
> databases.
> 
> > > Another general question I have is why can't the /system issue be
> > > fixed? Is there any good reason Android doesn't have symlinks like
> > > /bin->/system/bin, /etc->/system/etc, /lib->/system/lib,
> > > /tmp->/data/tmp, etc.? The gratuitous incompatibility is really
> > > disgusting.
> > 
> > First, android has /etc -> /system/etc in place, but,
> > unfortunately, no more :(
> > 
> > I made /etc -> /system/etc change just because I distrust symlinks
> > when doing security things. It is usually stable across devices,
> > but it's just symlink.
> > 
> > It even does not have usual Unix /tmp directory or it's surrogate
> > somewhere in filesystem. /data/tmp is my adoption, though it's
> > non-standard on android.
> > 
> > Second, android has a very different bootup process, and all those
> > links in / are created during bootup (on a tmpfs?). Sadly only /etc
> > is defined by android developers to be symlink to /system/etc.
> > 
> > Third, there are probably many differences between many android
> > device vendors, android OS types (different android versions
> > including ancient ones, different android forks that exist today,
> > vendor customisations of fs layout and in future many others). In
> > fact, android is _very_ fragmented OS.
> > 
> > All this is based on my experience with some android devices I
> > working (and worked) with.
> 
> If / is a tmpfs, I don't see why proper symlinks can't be created, or
> why /tmp can't just be created as a directory on / or as another tmpfs
> mount on /tmp. Obviously you can't do these kinds of things as a
> normal application installing on Android, but if you're doing your own
> system programming on Android or if you have root, this seems like the
> obvious correct fix...
> 
> I'd really like to hear from the Android side what their motive is for
> breaking this by not providing the proper symlinks.
> 
> Rich

Ok, I posted a version that is completely new in uid/gid translation,
which follows your suggestions.

It was really easy to implement it (although somewhat tricky with _r
functions at start) and no more malloc/free dances! It should be more
sane now.

Please see it (link is same):
http://lynxlynx.tk/prg/patches/musl-1.1.4_android.patch

As of previous version, I do not recommend it to be included in musl.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-21 10:34         ` Рысь
@ 2015-01-21 18:36           ` Rich Felker
  2015-01-22  2:37             ` Рысь
  0 siblings, 1 reply; 18+ messages in thread
From: Rich Felker @ 2015-01-21 18:36 UTC (permalink / raw)
  To: musl

On Wed, Jan 21, 2015 at 05:34:03PM +0700, Рысь wrote:
> В Sun, 18 Jan 2015 11:40:10 -0500
> Rich Felker <dalias@libc.org> пишет:
> 
> > On Sun, Jan 18, 2015 at 03:01:19PM +0700, Рысь wrote:
> > > В Sun, 18 Jan 2015 01:44:40 -0500
> > > Rich Felker <dalias@libc.org> пишет:
> > > 
> > > > On Sun, Jan 18, 2015 at 01:32:37PM +0700, Рысь wrote:
> > > > > В Thu, 15 Jan 2015 16:13:22 +0700
> > > > > Рысь <lynx@sibserver.ru> пишет:
> > > > > 
> > > > > > Hello all!
> > > > > > 
> > > > > > Are there any efforts or even a project which aims to port
> > > > > > musl to android platform?
> > > > > > 
> > > > > > For a year I slowly had built and running a couple of C tty
> > > > > > only programs such as iptables, tcpdump and of course busybox
> > > > > > and many others including my own with musl libc linked
> > > > > > statically. They work perfectly (no much differences between
> > > > > > an ARM phone and, for example, raspberry pi SoC) but a few
> > > > > > items I missed:
> > > > > > 
> > > > > > + Proper DNS resolving is not available
> > > > > > + Translation of android special user names is not done
> > > > > > 
> > > > > > As an advanced Linux user I know that android is not friendly
> > > > > > enough to plain C stuff and it's libc is even not finished
> > > > > > now so I aimed to port at least listed things to musl.
> > > > > > 
> > > > > > Because I am not going beyond listed items, a patch can be
> > > > > > developed just to support these inside musl-linked binaries.
> > > > > > 
> > > > > > I am first here or there is already someone who done this
> > > > > > before?
> > > > > 
> > > > > I made a patch to implement all three things for musl on
> > > > > android.
> > > > > 
> > > > > I do not post it here as attachment to this mail because it
> > > > > normally should not be integrated with musl. The patch itself
> > > > > is here:
> > > > > http://lynxlynx.tk/prg/patches/musl-1.1.4_android.patch, notes
> > > > > about it: http://lynxlynx.tk/eng/musl_android/.
> > > > > 
> > > > > Patch is invasive enough I think and not optimized and I agree
> > > > > with Rich that it must go as a special treat. I tried however
> > > > > move away all translating code to src/android and headers to
> > > > > include/android.
> > > > > 
> > > > > Patch is still in it's alpha stage, and probably will be changed
> > > > > often.
> > > > > 
> > > > > Modifications made for musl 1.1.4.
> > > > > 
> > > > > If anyone interested to audit it - welcome!
> > > > 
> > > > Thanks. If nothing else, this is very informative as to how
> > > > Android does things. I noticed a couple things that could be a
> > > > lot less invasive, I think, particularly the builtin
> > > > users/groups. Couldn't you just fmemopen() a constant string
> > > > inside libc in place of /etc/passwd or /etc/group and use the
> > > > existing code to parse it?
> > > 
> > > This sounds more interesting idea, I forgot that get*ent() open fd
> > > and there is fmemopen() function. But app_/ux_ax names still need a
> > > dedicated translation function, probably the same code which will
> > > form a passwd-like string and feed it into get*ent().
> > 
> > The intent is that get{gr,pw}{nam,uid} will eventually support
> > alternate backends via sending a request and receiving a response in
> > passwd/group line format. On normal systems this would take place via
> > a unix socket in some reasonable standard directory, but for Android
> > you could in principle build a reply mechanism into the binary in
> > place of it. Note that this would probably not support get{pw,gr}ent
> > enumeration, but I don't see that as a problem. Traditionally
> > enumeration does not work with backends like nis or ldap, as far as I
> > know, and it would be an unreasonable/abusive idiom on such large user
> > databases.
> > 
> > > > Another general question I have is why can't the /system issue be
> > > > fixed? Is there any good reason Android doesn't have symlinks like
> > > > /bin->/system/bin, /etc->/system/etc, /lib->/system/lib,
> > > > /tmp->/data/tmp, etc.? The gratuitous incompatibility is really
> > > > disgusting.
> > > 
> > > First, android has /etc -> /system/etc in place, but,
> > > unfortunately, no more :(
> > > 
> > > I made /etc -> /system/etc change just because I distrust symlinks
> > > when doing security things. It is usually stable across devices,
> > > but it's just symlink.
> > > 
> > > It even does not have usual Unix /tmp directory or it's surrogate
> > > somewhere in filesystem. /data/tmp is my adoption, though it's
> > > non-standard on android.
> > > 
> > > Second, android has a very different bootup process, and all those
> > > links in / are created during bootup (on a tmpfs?). Sadly only /etc
> > > is defined by android developers to be symlink to /system/etc.
> > > 
> > > Third, there are probably many differences between many android
> > > device vendors, android OS types (different android versions
> > > including ancient ones, different android forks that exist today,
> > > vendor customisations of fs layout and in future many others). In
> > > fact, android is _very_ fragmented OS.
> > > 
> > > All this is based on my experience with some android devices I
> > > working (and worked) with.
> > 
> > If / is a tmpfs, I don't see why proper symlinks can't be created, or
> > why /tmp can't just be created as a directory on / or as another tmpfs
> > mount on /tmp. Obviously you can't do these kinds of things as a
> > normal application installing on Android, but if you're doing your own
> > system programming on Android or if you have root, this seems like the
> > obvious correct fix...
> > 
> > I'd really like to hear from the Android side what their motive is for
> > breaking this by not providing the proper symlinks.
> > 
> > Rich
> 
> Ok, I posted a version that is completely new in uid/gid translation,
> which follows your suggestions.
> 
> It was really easy to implement it (although somewhat tricky with _r
> functions at start) and no more malloc/free dances! It should be more
> sane now.
> 
> Please see it (link is same):
> http://lynxlynx.tk/prg/patches/musl-1.1.4_android.patch
> 
> As of previous version, I do not recommend it to be included in musl.

It would be very much appreciated to send patches as attachments
rather than links. There's no way to have a well-documented ongoing
discussion of the patch if it's not in a permanent place for review,
and attached to the email/archives is the best way to achieve that.

Rich


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-21 18:36           ` Rich Felker
@ 2015-01-22  2:37             ` Рысь
  2015-01-31 15:08               ` Рысь
  0 siblings, 1 reply; 18+ messages in thread
From: Рысь @ 2015-01-22  2:37 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 459 bytes --]

В Wed, 21 Jan 2015 13:36:37 -0500
Rich Felker <dalias@libc.org> пишет:

> It would be very much appreciated to send patches as attachments
> rather than links. There's no way to have a well-documented ongoing
> discussion of the patch if it's not in a permanent place for review,
> and attached to the email/archives is the best way to achieve that.
> 
> Rich

Sorry.

Now patch is attached (I think it is more sane now to include it here)

[-- Attachment #2: musl-1.1.4_android.patch --]
[-- Type: application/octet-stream, Size: 33347 bytes --]

--- /dev/null
+++ musl-1.1.4/include/android/atz.h
@@ -0,0 +1,7 @@
+#define A_TZ_IDEXFILE "/system/usr/share/zoneinfo/zoneinfo.idx"
+#define A_TZ_ZONEFILE "/system/usr/share/zoneinfo/zoneinfo.dat"
+#define A_TZ_NAMELEN 40
+#define A_TZ_INTLEN 4
+
+int android_find_tz(const char *tzname, off_t *offs, size_t *len);
+int android_get_tz(unsigned char *out, size_t outl, off_t offs, size_t len);
--- /dev/null
+++ musl-1.1.4/include/android/idmap.h
@@ -0,0 +1,7 @@
+#define A_LNSIZE 256
+
+char *android_getpasswddb(size_t *sz);
+char *android_getgroupdb(size_t *sz);
+char *android_mkpasswd(const char *name, uid_t uid);
+char *android_mkgroup(const char *name, gid_t gid);
+int android_isappusr(const char *name);
--- /dev/null
+++ musl-1.1.4/include/android/istonum.h
@@ -0,0 +1,5 @@
+int __istonum(const char *s, long int *res);
+int __istonum_i(const char *s, int *res);
+int __istonum_sz(const char *s, size_t *res);
+int __istonum_uid(const char *s, uid_t *res);
+int __istonum_gid(const char *s, gid_t *res);
--- /dev/null
+++ musl-1.1.4/include/android/property.h
@@ -0,0 +1,10 @@
+extern int __prop_fd;
+extern size_t __prop_size;
+extern void *__prop_map;
+
+#define PROP_NAMELEN 32
+#define PROP_VALUELEN 92
+#define PROP_SERIALLEN 4
+
+int android_property_get(const char *name, char *val);
+int android_property_set(const char *name, const char *val);
--- /dev/null
+++ musl-1.1.4/include/android/version.h
@@ -0,0 +1 @@
+int android_get_version(int *maj, int *min, int *sub, int *rsvd);
--- musl-1.1.4.o/include/mntent.h
+++ musl-1.1.4/include/mntent.h
@@ -8,7 +8,7 @@
 #define __NEED_FILE
 #include <bits/alltypes.h>
 
-#define MOUNTED "/etc/mtab"
+#define MOUNTED "/proc/mounts"
 
 #define MNTTYPE_IGNORE	"ignore"
 #define MNTTYPE_NFS	"nfs"
--- musl-1.1.4.o/include/paths.h
+++ musl-1.1.4/include/paths.h
@@ -1,31 +1,31 @@
 #ifndef _PATHS_H
 #define _PATHS_H
 
-#define	_PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
-#define	_PATH_STDPATH "/bin:/usr/bin:/sbin:/usr/sbin"
+#define	_PATH_DEFPATH "/system/bin:/system/xbin:/vendor/bin"
+#define	_PATH_STDPATH "/system/bin:/system/xbin"
 
-#define	_PATH_BSHELL	"/bin/sh"
+#define	_PATH_BSHELL	"/system/bin/sh"
 #define	_PATH_CONSOLE	"/dev/console"
 #define	_PATH_DEVNULL	"/dev/null"
 #define	_PATH_KLOG	"/proc/kmsg"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
-#define	_PATH_MAILDIR	"/var/mail"
-#define	_PATH_MAN	"/usr/share/man"
+#define	_PATH_LASTLOG	"/data/misc/lastlog"
+#define	_PATH_MAILDIR	"/data/misc/mail"
+#define	_PATH_MAN	"/system/share/man"
 #define	_PATH_MNTTAB	"/etc/fstab"
-#define	_PATH_MOUNTED	"/etc/mtab"
+#define	_PATH_MOUNTED	"/proc/mounts"
 #define	_PATH_NOLOGIN	"/etc/nologin"
-#define	_PATH_SENDMAIL	"/usr/sbin/sendmail"
-#define	_PATH_SHADOW	"/etc/shadow"
-#define	_PATH_SHELLS	"/etc/shells"
+#define	_PATH_SENDMAIL	"/system/xbin/sendmail"
+#define	_PATH_SHADOW	"/system/etc/shadow"
+#define	_PATH_SHELLS	"/system/etc/shells"
 #define	_PATH_TTY	"/dev/tty"
 #define _PATH_UTMP	"/dev/null/utmp"
-#define	_PATH_VI	"/usr/bin/vi"
+#define	_PATH_VI	"/system/xbin/vi"
 #define _PATH_WTMP	"/dev/null/wtmp"
 
 #define	_PATH_DEV	"/dev/"
-#define	_PATH_TMP	"/tmp/"
-#define	_PATH_VARDB	"/var/lib/misc/"
-#define	_PATH_VARRUN	"/var/run/"
-#define	_PATH_VARTMP	"/var/tmp/"
+#define	_PATH_TMP	"/data/tmp/"
+#define	_PATH_VARDB	"/data/misc/"
+#define	_PATH_VARRUN	"/data/run/"
+#define	_PATH_VARTMP	"/data/tmp/"
 
 #endif
--- musl-1.1.4.o/include/resolv.h
+++ musl-1.1.4/include/resolv.h
@@ -64,7 +64,7 @@
 #define	__RES	19991006
 
 #ifndef _PATH_RESCONF
-#define _PATH_RESCONF        "/etc/resolv.conf"
+#define _PATH_RESCONF        "/system/etc/resolv.conf"
 #endif
 
 struct res_sym {
--- musl-1.1.4.o/include/stdio.h
+++ musl-1.1.4/include/stdio.h
@@ -154,7 +154,7 @@
 
 #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
  || defined(_BSD_SOURCE)
-#define P_tmpdir "/tmp"
+#define P_tmpdir "/data/tmp"
 char *tempnam(const char *, const char *);
 #endif
 
--- /dev/null
+++ musl-1.1.4/src/android/atz.c
@@ -0,0 +1,70 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <android/atz.h>
+#include "syscall.h"
+
+static int __toint(unsigned char *s)
+{
+	return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
+}
+
+int android_find_tz(const char *tzname, off_t *offs, size_t *len)
+{
+	size_t nl;
+	int fd = -1;
+	struct stat st;
+	unsigned char *map = MAP_FAILED, *p;
+
+	nl = strnlen(tzname, A_TZ_NAMELEN);
+
+	fd = open(A_TZ_IDEXFILE, O_RDONLY|O_CLOEXEC);
+	if (fd == -1) goto _err;
+
+	if (!fstat(fd, &st))
+		map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+
+	if (map == MAP_FAILED) goto _err;
+	close(fd);
+
+	p = memmem(map, st.st_size, tzname, nl);
+	if (!p) goto _err;
+
+	if (offs) *offs = (off_t)__toint(p + A_TZ_NAMELEN);
+	if (len) *len = (size_t)__toint(p + A_TZ_NAMELEN + A_TZ_INTLEN);
+
+	munmap(map, st.st_size);
+
+	return 1;
+
+_err:
+	if (map && st.st_size) munmap(map, st.st_size);
+	return 0;
+}
+
+int android_get_tz(unsigned char *out, size_t outl, off_t offs, size_t len)
+{
+	int fd = -1;
+
+	if (len > outl) goto _err;
+
+	fd = open(A_TZ_ZONEFILE, O_RDONLY|O_CLOEXEC);
+	if (fd == -1) goto _err;
+
+	if (lseek(fd, offs, SEEK_SET) == -1) goto _err;
+
+	if (read(fd, out, len) < len) goto _err;
+
+	close(fd);
+
+	return 1;
+
+_err:
+	if (fd != -1) close(fd);
+	return 0;
+}
--- /dev/null
+++ musl-1.1.4/src/android/idmap.c
@@ -0,0 +1,232 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <android/idmap.h>
+#include <android/istonum.h>
+#include <android/version.h>
+
+#define NOUID ((uid_t)-1)
+#define NOGID ((gid_t)-1)
+
+#define A_FIRSTAPPID 10000
+#define A_PERUSRAPPS 100000
+
+#define MULTISID(x) ((x-A_FIRSTAPPID)/A_PERUSRAPPS)
+#define SIDMULTI(x) ((x*A_PERUSRAPPS)+A_FIRSTAPPID)
+#define MULTIUID(x) (x-SIDMULTI(MULTISID(x)))
+
+static char __a_users[] =
+"root:x:0:0:android root:/data/root:/system/bin/sh\n"
+"system:x:1000:1000:android user:/:/system/bin/sh\n"
+"radio:x:1001:1001:android user:/:/system/bin/sh\n"
+"bluetooth:x:1002:1002:android user:/:/system/bin/sh\n"
+"graphics:x:1003:1003:android user:/:/system/bin/sh\n"
+"input:x:1004:1004:android user:/:/system/bin/sh\n"
+"audio:x:1005:1005:android user:/:/system/bin/sh\n"
+"camera:x:1006:1006:android user:/:/system/bin/sh\n"
+"log:x:1007:1007:android user:/:/system/bin/sh\n"
+"compass:x:1008:1008:android user:/:/system/bin/sh\n"
+"mount:x:1009:1009:android user:/:/system/bin/sh\n"
+"wifi:x:1010:1010:android user:/:/system/bin/sh\n"
+"adb:x:1011:1011:android user:/:/system/bin/sh\n"
+"install:x:1012:1012:android user:/:/system/bin/sh\n"
+"media:x:1013:1013:android user:/:/system/bin/sh\n"
+"dhcp:x:1014:1014:android user:/:/system/bin/sh\n"
+"sdcard_rw:x:1015:1015:android user:/:/system/bin/sh\n"
+"vpn:x:1016:1016:android user:/:/system/bin/sh\n"
+"keystore:x:1017:1017:android user:/:/system/bin/sh\n"
+"usb:x:1018:1018:android user:/:/system/bin/sh\n"
+"drm:x:1019:1019:android user:/:/system/bin/sh\n"
+"available:x:1020:1020:android user:/:/system/bin/sh\n"
+"gps:x:1021:1021:android user:/:/system/bin/sh\n"
+"media_rw:x:1023:1023:android user:/:/system/bin/sh\n"
+"mtp:x:1024:1024:android user:/:/system/bin/sh\n"
+"nfc:x:1027:1027:android user:/:/system/bin/sh\n"
+"shell:x:2000:2000:android shell:/data:/system/bin/sh\n"
+"cache:x:2001:2001:android user:/:/system/bin/sh\n"
+"diag:x:2002:2002:android user:/:/system/bin/sh\n"
+"misc:x:9998:9998:android user:/:/system/bin/sh\n"
+"nobody:x:9999:9999:android nobody:/:/system/bin/sh\n"
+;
+
+static char __a_groups[] =
+"root:x:0:\n"
+"system:x:1000:\n"
+"radio:x:1001:\n"
+"bluetooth:x:1002:\n"
+"graphics:x:1003:\n"
+"input:x:1004:\n"
+"audio:x:1005:\n"
+"camera:x:1006:\n"
+"log:x:1007:\n"
+"compass:x:1008:\n"
+"mount:x:1009:\n"
+"wifi:x:1010:\n"
+"adb:x:1011:\n"
+"install:x:1012:\n"
+"media:x:1013:\n"
+"dhcp:x:1014:\n"
+"sdcard_rw:x:1015:\n"
+"vpn:x:1016:\n"
+"keystore:x:1017:\n"
+"usb:x:1018:\n"
+"drm:x:1019:\n"
+"available:x:1020:\n"
+"gps:x:1021:\n"
+"media_rw:x:1023:\n"
+"mtp:x:1024:\n"
+"drmrpc:x:1026:\n"
+"nfc:x:1027:\n"
+"shell:x:2000:\n"
+"cache:x:2001:\n"
+"diag:x:2002:\n"
+"net_bt_admin:x:3001:\n"
+"net_bt:x:3002:\n"
+"inet:x:3003:\n"
+"net_raw:x:3004:\n"
+"net_admin:x:3005:\n"
+"net_bw_stats:x:3006:\n"
+"net_bw_acct:x:3007:\n"
+"misc:x:9998:\n"
+"nobody:x:9999:\n"
+;
+
+static char gecos[] = "android virtual";
+
+static int __issuper(void)
+{
+	return !!(getuid() == 0);
+}
+
+static char *__xgetenv(const char *name)
+{
+	if (__issuper()) return getenv(name);
+	else return NULL;
+}
+
+static int __a_is_multiuser(void)
+{
+	int maj, min;
+
+	if (!android_get_version(&maj, &min, NULL, NULL)) return 0;
+	if (maj >= 5) return 1;
+	if (maj == 4) {
+		if (min >= 1) return 1;
+		else return 0;
+	}
+	if (maj <= 3) return 0;
+}
+
+char *android_getpasswddb(size_t *sz)
+{
+	*sz = sizeof(__a_users);
+	return __a_users;
+}
+
+char *android_getgroupdb(size_t *sz)
+{
+	*sz = sizeof(__a_groups);
+	return __a_groups;
+}
+
+char *android_mkpasswd(const char *name, uid_t uid)
+{
+	static char p[A_LNSIZE];
+	char *udir = "/data";
+	char *sh = "/system/bin/sh";
+	char *s, *d;
+
+	memset(p, 0, sizeof(p));
+
+	s = __xgetenv("_A_USERDIR");
+	if (s) udir = s;
+	s = __xgetenv("_A_SHELL");
+	if (s) sh = s;
+
+	if (name) {
+		uid_t a, b;
+		if (__a_is_multiuser() && *name == 'u' && strchr(name, '_')) {
+			strncpy(p, name, A_LNSIZE);
+			s = p+1;
+			d = strstr(s, "_a");
+			if (!d) return NULL;
+			*d = 0; d += 2;
+			if (!__istonum_uid(s, &a)) return NULL;
+			if (!__istonum_uid(d, &b)) return NULL;
+			uid = SIDMULTI(a)+b;
+		}
+		else if (!strncmp(name, "app_", 4)) {
+			uid_t y;
+			const char *S;
+
+			S = name+4;
+			if (!__istonum_uid(S, &y)) return NULL;
+			uid = y+A_FIRSTAPPID;
+		}
+		else return NULL;
+
+		snprintf(p, sizeof(p), "%s:x:%u:%u:%s:%s:%s", name, uid, uid, gecos, udir, sh);
+	}
+	else if (uid >= A_FIRSTAPPID) {
+		if (__a_is_multiuser())
+			snprintf(p, sizeof(p), "u%u_a%u:x:%u:%u:%s:%s:%s", MULTISID(uid), MULTIUID(uid), uid, uid, gecos, udir, sh);
+		else
+			snprintf(p, sizeof(p), "app_%u:x:%u:%u:%s:%s:%s", uid-A_FIRSTAPPID, uid, uid, gecos, udir, sh);
+	}
+	else return NULL;
+
+	return p;
+}
+
+char *android_mkgroup(const char *name, gid_t gid)
+{
+	static char g[A_LNSIZE];
+	char *s, *d;
+
+	memset(g, 0, sizeof(g));
+
+	if (name) {
+		if (__a_is_multiuser() && *name == 'u' && strchr(name, '_')) {
+			gid_t a, b;
+
+			strncpy(g, name, A_LNSIZE);
+			s = g+1;
+			d = strstr(s, "_a");
+			if (!d) return NULL;
+			*d = 0; d += 2;
+			if (!__istonum_gid(s, &a)) return NULL;
+			if (!__istonum_gid(d, &b)) return NULL;
+			gid = SIDMULTI(a)+b;
+		}
+		else if (!strncmp(name, "app_", 4)) {
+			gid_t y;
+			const char *S;
+
+			S = name+4;
+			if (!__istonum_gid(S, &y)) return NULL;
+			else gid = y+A_FIRSTAPPID;
+		}
+		else return NULL;
+
+		snprintf(g, sizeof(g), "%s:x:%u:", name, gid);
+	}
+	else if (gid >= A_FIRSTAPPID) {
+		if (__a_is_multiuser())
+			snprintf(g, sizeof(g), "u%u_a%u:x:%u:", MULTISID(gid), MULTIUID(gid), gid);
+		else
+			snprintf(g, sizeof(g), "app_%u:x:%u:", gid-A_FIRSTAPPID, gid);
+	}
+	else return NULL;
+
+	return g;
+}
+
+int android_isappusr(const char *name)
+{
+	char *p;
+
+	p = android_mkpasswd(name, 0);
+	return (p == 0);
+}
--- /dev/null
+++ musl-1.1.4/src/android/istonum.c
@@ -0,0 +1,48 @@
+#include <sys/types.h>
+#include <stdlib.h>
+#include <android/istonum.h>
+
+int __istonum(const char *s, long int *res)
+{
+	char *p;
+	if (!s || *s == 0) return 0;
+	if (res) *res = strtol(s, &p, 10);
+	else strtol(s, &p, 10);
+	return (*p == 0);
+}
+
+int __istonum_i(const char *s, int *res)
+{
+	long int x = 0;
+	int y;
+	y = __istonum(s, &x);
+	*res = (int)x;
+	return y;
+}
+
+int __istonum_sz(const char *s, size_t *res)
+{
+	long int x = 0;
+	int y;
+	y = __istonum(s, &x);
+	*res = (size_t)x;
+	return y;
+}
+
+int __istonum_uid(const char *s, uid_t *res)
+{
+	long int x = 0;
+	int y;
+	y = __istonum(s, &x);
+	*res = (uid_t)x;
+	return y;
+}
+
+int __istonum_gid(const char *s, gid_t *res)
+{
+	long int x = 0;
+	int y;
+	y = __istonum(s, &x);
+	*res = (gid_t)x;
+	return y;
+}
--- /dev/null
+++ musl-1.1.4/src/android/property.c
@@ -0,0 +1,92 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <android/istonum.h>
+#include <android/property.h>
+
+int __prop_fd = -1;
+size_t __prop_size = 0;
+void *__prop_map = NULL;
+
+static int __android_init_prop(void)
+{
+	char propcfg[64];
+	char *s, *d;
+
+	if (__prop_map) return 1;
+
+	s = getenv("ANDROID_PROPERTY_WORKSPACE");
+	if (!s) return 0;
+	strncpy(propcfg, s, sizeof(propcfg)); s = propcfg;
+
+	d = strchr(s, ',');
+	if (!d) return 0;
+	*d = 0; d++;
+
+	if (!__istonum_i(s, &__prop_fd)) return 0;
+	if (!__istonum_sz(d, &__prop_size)) return 0;
+
+	__prop_map = mmap(NULL, __prop_size, PROT_READ, MAP_SHARED, __prop_fd, 0);
+
+	if (__prop_map == MAP_FAILED) {
+		__prop_map = NULL;
+		return 0;
+	}
+
+	return 1;
+}
+
+#if 0
+static void __android_fini_prop(void)
+{
+	munmap(__prop_map, __prop_size);
+	__prop_map = NULL; __prop_size = 0;
+}
+#endif
+
+int android_property_get(const char *name, char *val)
+{
+	char *s, *d;
+	size_t nl;
+
+	if (!__android_init_prop()) return 0;
+
+	nl = strnlen(name, PROP_NAMELEN);
+	s = memmem(__prop_map, __prop_size, name, nl);
+
+	if (!s) return 0;
+
+	d = s+PROP_NAMELEN+PROP_SERIALLEN;
+	strncpy(val, d, PROP_VALUELEN);
+
+	return 1;
+}
+
+#if 0
+int android_property_getonce(const char *name, char *val)
+{
+	int r;
+
+	r = android_property_get(name, val);
+	__android_fini_prop();
+}
+
+char *android_getprop(const char *name)
+{
+	static char *r;
+
+	if (!r) r = malloc(PROP_VALUELEN);
+	if (!r) return r;
+	if (!android_property_get(name, r)) return NULL;
+	return r;
+}
+#endif
+
+int android_property_set(const char *name, const char *val)
+{
+	/* Sorry, unimplemented */
+	return 0;
+}
--- /dev/null
+++ musl-1.1.4/src/android/version.c
@@ -0,0 +1,62 @@
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <android/istonum.h>
+#include <android/property.h>
+
+int android_get_version(int *maj, int *min, int *sub, int *rsvd)
+{
+	char verstr[PROP_VALUELEN] = {0};
+	char *s, *d, *t;
+	int x;
+
+	if (!android_property_get("ro.build.version.release", verstr)) goto _err;
+
+	if (maj) *maj = 0;
+	if (min) *min = 0;
+	if (sub) *sub = 0;
+	if (rsvd) *rsvd = 0;
+
+	s = d = verstr; t = NULL; x = 0;
+	while ((s = strtok_r(d, ".", &t))) {
+		if (d) d = NULL;
+
+		switch (x) {
+			case 0: if (maj) if (!__istonum_i(s, maj)) goto _err; break;
+			case 1: if (min) if (!__istonum_i(s, min)) goto _err; break;
+			case 2: if (sub) if (!__istonum_i(s, sub)) goto _err; break;
+			case 3: if (rsvd) if (!__istonum_i(s, rsvd)) goto _err; break;
+		}
+
+		x++;
+	}
+
+	return 1;
+_err:	return 0;
+}
+
+#if 0
+int android_get_major(void)
+{
+	int r;
+
+	if (!android_get_version(&r, NULL, NULL, NULL)) return -1;
+	return r;
+}
+
+int android_get_minor(void)
+{
+	int r;
+
+	if (!android_get_version(NULL, &r, NULL, NULL)) return -1;
+	return r;
+}
+
+int android_get_subminor(void)
+{
+	int r;
+
+	if (!android_get_version(NULL, NULL, &r, NULL)) return -1;
+	return r;
+}
+#endif
--- musl-1.1.4.o/src/conf/confstr.c
+++ musl-1.1.4/src/conf/confstr.c
@@ -6,7 +6,7 @@
 {
 	const char *s = "";
 	if (!name) {
-		s = "/bin:/usr/bin";
+		s = "/system/bin:/system/xbin";
 	} else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>31U) {
 		errno = EINVAL;
 		return 0;
--- musl-1.1.4.o/src/ldso/dynlink.c
+++ musl-1.1.4/src/ldso/dynlink.c
@@ -751,7 +751,7 @@
 					sys_path = "";
 				}
 			}
-			if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
+			if (!sys_path) sys_path = "/system/lib:/system/xlib:/vendor/lib";
 			fd = path_open(name, sys_path, buf, sizeof buf);
 		}
 		pathname = buf;
--- musl-1.1.4.o/src/legacy/getusershell.c
+++ musl-1.1.4/src/legacy/getusershell.c
@@ -2,7 +2,7 @@
 #include <stdio.h>
 #include <unistd.h>
 
-static const char defshells[] = "/bin/sh\n/bin/csh\n";
+static const char defshells[] = "/system/bin/sh\n/system/bin/csh\n";
 
 static char *line;
 static size_t linesize;
@@ -16,7 +16,7 @@
 
 void setusershell(void)
 {
-	if (!f) f = fopen("/etc/shells", "rbe");
+	if (!f) f = fopen("/system/etc/shells", "rbe");
 	if (!f) f = fmemopen((void *)defshells, sizeof defshells - 1, "rb");
 }
 
--- musl-1.1.4.o/src/misc/getgrouplist.c
+++ musl-1.1.4/src/misc/getgrouplist.c
@@ -1,8 +1,13 @@
 #define _GNU_SOURCE
+#include <sys/types.h>
+#include <pwd.h>
 #include <grp.h>
 #include <string.h>
 #include <limits.h>
+#include <android/idmap.h>
 
+struct group *__getgrent_android();
+
 int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
 {
 	size_t n, i;
@@ -12,6 +17,8 @@
 	*groups++ = gid;
 	*ngroups = 1;
 
+	if (android_isappusr(user)) goto _end;
+
 	setgrent();
 	while ((gr = getgrent()) && *ngroups < INT_MAX) {
 		for (i=0; gr->gr_mem[i] && strcmp(user, gr->gr_mem[i]); i++);
@@ -20,5 +27,13 @@
 	}
 	endgrent();
 
-	return *ngroups > n ? -1 : *ngroups;
+	setgrent();
+	while ((gr = __getgrent_android()) && *ngroups < INT_MAX) {
+		for (i=0; gr->gr_mem[i] && strcmp(user, gr->gr_mem[i]); i++);
+		if (!gr->gr_mem[i]) continue;
+		if (++*ngroups <= n) *groups++ = gr->gr_gid;
+	}
+	endgrent();
+
+_end:	return *ngroups > n ? -1 : *ngroups;
 }
--- musl-1.1.4.o/src/misc/wordexp.c
+++ musl-1.1.4/src/misc/wordexp.c
@@ -113,7 +113,7 @@
 	if (!pid) {
 		if (p[1] == 1) fcntl(1, F_SETFD, 0);
 		else dup2(p[1], 1);
-		execl("/bin/sh", "sh", "-c",
+		execl("/system/bin/sh", "sh", "-c",
 			"eval \"printf %s\\\\\\\\0 x $1 $2\"",
 			"sh", s, redir, (char *)0);
 		_exit(1);
--- musl-1.1.4.o/src/network/getnameinfo.c
+++ musl-1.1.4/src/network/getnameinfo.c
@@ -50,7 +50,7 @@
 	char line[512], *p, *z;
 	unsigned char _buf[1032], atmp[16];
 	struct address iplit;
-	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
+	FILE _f, *f = __fopen_rb_ca("/system/etc/hosts", &_f, _buf, sizeof _buf);
 	if (!f) return;
 	if (family == AF_INET) {
 		memcpy(atmp+12, a, 4);
@@ -90,7 +90,7 @@
 	unsigned long svport;
 	char line[128], *p, *z;
 	unsigned char _buf[1032];
-	FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
+	FILE _f, *f = __fopen_rb_ca("/system/etc/services", &_f, _buf, sizeof _buf);
 	if (!f) return;
 	while (fgets(line, sizeof line, f)) {
 		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
--- musl-1.1.4.o/src/network/lookup_name.c
+++ musl-1.1.4/src/network/lookup_name.c
@@ -50,7 +50,7 @@
 	size_t l = strlen(name);
 	int cnt = 0;
 	unsigned char _buf[1032];
-	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
+	FILE _f, *f = __fopen_rb_ca("/system/etc/hosts", &_f, _buf, sizeof _buf);
 	if (!f) return 0;
 	while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
 		char *p, *z;
--- musl-1.1.4.o/src/network/lookup_serv.c
+++ musl-1.1.4/src/network/lookup_serv.c
@@ -36,7 +36,7 @@
 	size_t l = strlen(name);
 
 	unsigned char _buf[1032];
-	FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
+	FILE _f, *f = __fopen_rb_ca("/system/etc/services", &_f, _buf, sizeof _buf);
 	if (!f) return EAI_SERVICE;
 
 	while (fgets(line, sizeof line, f) && cnt < MAXSERVS) {
--- musl-1.1.4.o/src/network/res_msend.c
+++ musl-1.1.4/src/network/res_msend.c
@@ -13,6 +13,7 @@
 #include "stdio_impl.h"
 #include "syscall.h"
 #include "lookup.h"
+#include <android/property.h>
 
 static void cleanup(void *p)
 {
@@ -53,7 +54,7 @@
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 
 	/* Get nameservers from resolv.conf, fallback to localhost */
-	f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
+	f = __fopen_rb_ca("/system/etc/resolv.conf", &_f, _buf, sizeof _buf);
 	if (f) for (nns=0; nns<3 && fgets(line, sizeof line, f); ) {
 		if (!strncmp(line, "options", 7) && isspace(line[7])) {
 			unsigned long x;
@@ -93,7 +94,30 @@
 		}
 	}
 	if (f) __fclose_ca(f);
+
+	/* if there is no /etc/resolv.conf, then get nameservers from android config */
 	if (!nns) {
+		strcpy(line, "net.dns1");
+_second:	if (line[7] > '2') goto _out;
+		if (android_property_get(line, (char *)_buf)) {
+			if (__lookup_ipliteral(&iplit, (char *)_buf, AF_UNSPEC)>0) {
+				if (iplit.family == AF_INET) {
+					memcpy(&ns[nns].sin.sin_addr, iplit.addr, 4);
+					ns[nns].sin.sin_port = htons(53);
+					ns[nns++].sin.sin_family = AF_INET;
+				}
+				else {
+					sl = sizeof sa.sin6;
+					memcpy(&ns[nns].sin6.sin6_addr, iplit.addr, 16);
+					ns[nns].sin6.sin6_port = htons(53);
+					ns[nns].sin6.sin6_scope_id = iplit.scopeid;
+					ns[nns++].sin6.sin6_family = family = AF_INET6;
+				}
+			}
+		}
+		line[7]++; goto _second;
+	}
+_out:	if (!nns) {
 		ns[0].sin.sin_family = AF_INET;
 		ns[0].sin.sin_port = htons(53);
 		ns[0].sin.sin_addr.s_addr = htonl(0x7f000001);
--- musl-1.1.4.o/src/passwd/getgr_r.c
+++ musl-1.1.4/src/passwd/getgr_r.c
@@ -1,11 +1,11 @@
 #include "pwf.h"
 #include <pthread.h>
+#include <android/idmap.h>
 
 #define FIX(x) (gr->gr_##x = gr->gr_##x-line+buf)
 
-static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+static int getgr_r(FILE *f, const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
 {
-	FILE *f;
 	char *line = 0;
 	size_t len = 0;
 	char **mem = 0;
@@ -16,13 +16,13 @@
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 
-	f = fopen("/etc/group", "rbe");
+	*res = 0;
+	if (!f) f = fopen("/system/etc/group", "rbe");
 	if (!f) {
 		rv = errno;
 		goto done;
 	}
 
-	*res = 0;
 	while (__getgrent_a(f, gr, &line, &len, &mem, &nmem)) {
 		if (name && !strcmp(name, gr->gr_name)
 		|| !name && gr->gr_gid == gid) {
@@ -51,12 +51,55 @@
 	return rv;
 }
 
+static int __getgr_android_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	char *p;
+	size_t sz;
+	FILE *f;
+
+	*res = 0;
+	p = android_getgroupdb(&sz);
+	if (!p) return 0;
+
+	f = fmemopen(p, sz, "rb");
+	if (!f) return 0;
+
+	return getgr_r(f, name, gid, gr, buf, size, res);
+}
+
+static int __getgr_android_app_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	char *p;
+	size_t sz;
+	FILE *f;
+
+	*res = 0;
+	p = android_mkgroup(name, gid);
+	if (!p) return 0;
+	sz = strnlen(p, A_LNSIZE)+1;
+
+	f = fmemopen(p, sz, "rb");
+	if (!f) return 0;
+
+	return getgr_r(f, name, gid, gr, buf, size, res);
+}
+
 int getgrnam_r(const char *name, struct group *gr, char *buf, size_t size, struct group **res)
 {
-	return getgr_r(name, 0, gr, buf, size, res);
+	int r;
+
+	r = getgr_r(0, name, 0, gr, buf, size, res);
+	if (!*res) __getgr_android_r(name, 0, gr, buf, size, res);
+	if (!*res) __getgr_android_app_r(name, 0, gr, buf, size, res);
+	return r;
 }
 
 int getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
 {
-	return getgr_r(0, gid, gr, buf, size, res);
+	int r;
+
+	r = getgr_r(0, 0, gid, gr, buf, size, res);
+	if (!*res) __getgr_android_r(0, gid, gr, buf, size, res);
+	if (!*res) __getgr_android_app_r(0, gid, gr, buf, size, res);
+	return r;
 }
--- musl-1.1.4.o/src/passwd/getgrent.c
+++ musl-1.1.4/src/passwd/getgrent.c
@@ -1,6 +1,9 @@
 #include "pwf.h"
+#include <android/idmap.h>
 
 static FILE *f;
+static char *line, **mem;
+static struct group grs;
 
 void setgrent()
 {
@@ -12,14 +15,45 @@
 
 struct group *getgrent()
 {
-	static char *line, **mem;
-	static struct group gr;
 	size_t size=0, nmem=0;
-	if (!f) f = fopen("/etc/group", "rbe");
+	if (!f) f = fopen("/system/etc/group", "rbe");
 	if (!f) return 0;
-	return __getgrent_a(f, &gr, &line, &size, &mem, &nmem);
+	return __getgrent_a(f, &grs, &line, &size, &mem, &nmem);
 }
 
+struct group *__getgrent_android()
+{
+	char *p;
+	size_t size, nmem=0;
+
+	if (!f) {
+		p = android_getgroupdb(&size);
+		if (!p) return 0;
+
+		f = fmemopen(p, size, "rb");
+		if (!f) return 0;
+	}
+
+	return __getgrent_a(f, &grs, &line, &size, &mem, &nmem);
+}
+
+static struct group *__getgr_android_app(const char *name, gid_t gid)
+{
+	char *p;
+	size_t size, nmem=0;
+
+	if (!f) {
+		p = android_mkgroup(name, gid);
+		if (!p) return 0;
+		size = strnlen(p, A_LNSIZE)+1;
+
+		f = fmemopen(p, size, "rb");
+		if (!f) return 0;
+	}
+
+	return __getgrent_a(f, &grs, &line, &size, &mem, &nmem);
+}
+
 struct group *getgrgid(gid_t gid)
 {
 	struct group *gr;
@@ -28,6 +62,14 @@
 	while ((gr=getgrent()) && gr->gr_gid != gid);
 	errno_saved = errno;
 	endgrent();
+	if (!gr) {
+		setgrent();
+		while ((gr=__getgrent_android()) && gr->gr_gid != gid);
+		endgrent();
+	}
+	setgrent();
+	if (!gr) gr = __getgr_android_app(NULL, gid);
+	endgrent();
 	errno = errno_saved;
 	return gr;
 }
@@ -39,6 +81,14 @@
 	setgrent();
 	while ((gr=getgrent()) && strcmp(gr->gr_name, name));
 	errno_saved = errno;
+	endgrent();
+	if (!gr) {
+		setgrent();
+		while ((gr=__getgrent_android()) && strcmp(gr->gr_name, name));
+		endgrent();
+	}
+	setgrent();
+	if (!gr) gr = __getgr_android_app(name, 0);
 	endgrent();
 	errno = errno_saved;
 	return gr;
--- musl-1.1.4.o/src/passwd/getpw_r.c
+++ musl-1.1.4/src/passwd/getpw_r.c
@@ -1,11 +1,11 @@
 #include "pwf.h"
 #include <pthread.h>
+#include <android/idmap.h>
 
 #define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)
 
-static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+static int getpw_r(FILE *f, const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
 {
-	FILE *f;
 	char *line = 0;
 	size_t len = 0;
 	int rv = 0;
@@ -13,13 +13,13 @@
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 
-	f = fopen("/etc/passwd", "rbe");
+	*res = 0;
+	if (!f) f = fopen("/system/etc/passwd", "rbe");
 	if (!f) {
 		rv = errno;
 		goto done;
 	}
 
-	*res = 0;
 	while (__getpwent_a(f, pw, &line, &len)) {
 		if (name && !strcmp(name, pw->pw_name)
 		|| !name && pw->pw_uid == uid) {
@@ -37,19 +37,63 @@
 			break;
 		}
 	}
- 	free(line);
+	free(line);
 	fclose(f);
 done:
 	pthread_setcancelstate(cs, 0);
 	return rv;
 }
 
+static int __getpw_android_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	char *p;
+	size_t sz;
+	FILE *f;
+
+	*res = 0;
+	p = android_getpasswddb(&sz);
+	if (!p) return 0;
+
+	f = fmemopen(p, sz, "rb");
+	if (!f) return 0;
+
+	return getpw_r(f, name, uid, pw, buf, size, res);
+}
+
+static int __getpw_android_app_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	char *p;
+	size_t sz;
+	FILE *f;
+
+	*res = 0;
+	p = android_mkpasswd(name, uid);
+	if (!p) return 0;
+	sz = strnlen(p, A_LNSIZE)+1;
+
+	f = fmemopen(p, sz, "rb");
+	if (!f) return 0;
+
+	return getpw_r(f, name, uid, pw, buf, size, res);
+}
+
 int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)
 {
-	return getpw_r(name, 0, pw, buf, size, res);
+	int r;
+
+	r = getpw_r(0, name, 0, pw, buf, size, res);
+	if (!*res) __getpw_android_r(name, 0, pw, buf, size, res);
+	if (!*res) __getpw_android_app_r(name, 0, pw, buf, size, res);
+	return r;
 }
 
 int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
 {
-	return getpw_r(0, uid, pw, buf, size, res);
+	int r;
+
+	r = getpw_r(0, 0, uid, pw, buf, size, res);
+	/* dispose any android errors */
+	if (!*res) __getpw_android_r(0, uid, pw, buf, size, res);
+	if (!*res) __getpw_android_app_r(0, uid, pw, buf, size, res);
+	return r;
 }
--- musl-1.1.4.o/src/passwd/getpwent.c
+++ musl-1.1.4/src/passwd/getpwent.c
@@ -1,6 +1,9 @@
 #include "pwf.h"
+#include <android/idmap.h>
 
 static FILE *f;
+static char *line;
+static struct passwd pws;
 
 void setpwent()
 {
@@ -12,14 +15,46 @@
 
 struct passwd *getpwent()
 {
-	static char *line;
-	static struct passwd pw;
+	struct passwd *r;
 	size_t size=0;
-	if (!f) f = fopen("/etc/passwd", "rbe");
+	if (!f) f = fopen("/system/etc/passwd", "rbe");
 	if (!f) return 0;
-	return __getpwent_a(f, &pw, &line, &size);
+	return __getpwent_a(f, &pws, &line, &size);
 }
 
+static struct passwd *__getpwent_android()
+{
+	char *p;
+	size_t size;
+
+	if (!f) {
+		p = android_getpasswddb(&size);
+		if (!p) return 0;
+
+		f = fmemopen(p, size, "rb");
+		if (!f) return 0;
+	}
+
+	return __getpwent_a(f, &pws, &line, &size);
+}
+
+static struct passwd *__getpw_android_app(const char *name, uid_t uid)
+{
+	char *p;
+	size_t size;
+
+	if (!f) {
+		p = android_mkpasswd(name, uid);
+		if (!p) return 0;
+		size = strnlen(p, A_LNSIZE)+1;
+
+		f = fmemopen(p, size, "rb");
+		if (!f) return 0;
+	}
+
+	return __getpwent_a(f, &pws, &line, &size);
+}
+
 struct passwd *getpwuid(uid_t uid)
 {
 	struct passwd *pw;
@@ -28,6 +63,16 @@
 	while ((pw=getpwent()) && pw->pw_uid != uid);
 	errno_saved = errno;
 	endpwent();
+	/* ask about android defined virtual users */
+	if (!pw) {
+		setpwent();
+		while ((pw=__getpwent_android()) && pw->pw_uid != uid);
+		endpwent();
+	}
+	/* for "app_XX"/"uX_aYY" translation you still need a dedicated function... */
+	setpwent();
+	if (!pw) pw = __getpw_android_app(NULL, uid);
+	endpwent();
 	errno = errno_saved;
 	return pw;
 }
@@ -39,6 +84,14 @@
 	setpwent();
 	while ((pw=getpwent()) && strcmp(pw->pw_name, name));
 	errno_saved = errno;
+	endpwent();
+	if (!pw) {
+		setpwent();
+		while ((pw=__getpwent_android()) && strcmp(pw->pw_name, name));
+		endpwent();
+	}
+	setpwent();
+	if (!pw) pw = __getpw_android_app(name, 0);
 	endpwent();
 	errno = errno_saved;
 	return pw;
--- musl-1.1.4.o/src/process/execvp.c
+++ musl-1.1.4/src/process/execvp.c
@@ -18,7 +18,7 @@
 	if (strchr(file, '/'))
 		return execve(file, argv, envp);
 
-	if (!path) path = "/usr/local/bin:/bin:/usr/bin";
+	if (!path) path = "/system/bin:/system/xbin:/vendor/bin";
 	k = strnlen(file, NAME_MAX+1);
 	if (k > NAME_MAX) {
 		errno = ENAMETOOLONG;
--- musl-1.1.4.o/src/process/system.c
+++ musl-1.1.4/src/process/system.c
@@ -33,7 +33,7 @@
 	posix_spawnattr_setsigmask(&attr, &old);
 	posix_spawnattr_setsigdefault(&attr, &reset);
 	posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK);
-	ret = posix_spawn(&pid, "/bin/sh", 0, &attr,
+	ret = posix_spawn(&pid, "/system/bin/sh", 0, &attr,
 		(char *[]){"sh", "-c", (char *)cmd, 0}, __environ);
 	posix_spawnattr_destroy(&attr);
 
--- musl-1.1.4.o/src/stdio/popen.c
+++ musl-1.1.4/src/stdio/popen.c
@@ -51,7 +51,7 @@
 	e = ENOMEM;
 	if (!posix_spawn_file_actions_init(&fa)) {
 		if (!posix_spawn_file_actions_adddup2(&fa, p[1-op], 1-op)) {
-			if (!(e = posix_spawn(&pid, "/bin/sh", &fa, 0,
+			if (!(e = posix_spawn(&pid, "/system/bin/sh", &fa, 0,
 			    (char *[]){ "sh", "-c", (char *)cmd, 0 }, __environ))) {
 				posix_spawn_file_actions_destroy(&fa);
 				f->pipe_pid = pid;
--- musl-1.1.4.o/src/stdio/tmpfile.c
+++ musl-1.1.4/src/stdio/tmpfile.c
@@ -8,7 +8,7 @@
 
 FILE *tmpfile(void)
 {
-	char s[] = "/tmp/tmpfile_XXXXXX";
+	char s[] = "/data/tmp/tmpfile_XXXXXX";
 	int fd;
 	FILE *f;
 	int try;
--- musl-1.1.4.o/src/stdio/tmpnam.c
+++ musl-1.1.4/src/stdio/tmpnam.c
@@ -12,7 +12,7 @@
 char *tmpnam(char *buf)
 {
 	static char internal[L_tmpnam];
-	char s[] = "/tmp/tmpnam_XXXXXX";
+	char s[] = "/data/tmp/tmpnam_XXXXXX";
 	int try;
 	int r;
 	for (try=0; try<MAXTRIES; try++) {
--- musl-1.1.4.o/src/time/__tz.c
+++ musl-1.1.4/src/time/__tz.c
@@ -1,9 +1,12 @@
-#include "time_impl.h"
 #include <stdint.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
+#include "time_impl.h"
 #include "libc.h"
+#include <android/property.h>
+#include <android/atz.h>
 
 long  __timezone = 0;
 int   __daylight = 0;
@@ -121,14 +124,19 @@
 static void do_tzset()
 {
 	char buf[NAME_MAX+25], *pathname=buf+24;
+	char atz[PROP_VALUELEN]; unsigned char atzdata[2048];
+	off_t aoffs; size_t alen;
 	const char *try, *s, *p;
 	const unsigned char *map = 0;
 	size_t i;
 	static const char search[] =
-		"/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
+		"/system/share/zoneinfo/\0/system/usr/share/zoneinfo/\0/etc/zoneinfo/\0";
 
 	s = getenv("TZ");
-	if (!s || !*s) s = "/etc/localtime";
+	if (!s || !*s) {
+		s = "/system/etc/localtime";
+		if (android_property_get("persist.sys.timezone", atz)) s = atz;
+	}
 
 	if (old_tz && !strcmp(s, old_tz)) return;
 
@@ -147,13 +155,22 @@
 	}
 	if (old_tz) memcpy(old_tz, s, i+1);
 
+	if (s == atz) {
+		if (android_find_tz(s, &aoffs, &alen)
+		    && android_get_tz(atzdata, sizeof(atzdata), aoffs, alen)) {
+			map = atzdata;
+			map_size = alen;
+		}
+		else s = __gmt;
+	}
+	else {
 	/* Non-suid can use an absolute tzfile pathname or a relative
 	 * pathame beginning with "."; in secure mode, only the
 	 * standard path will be searched. */
 	if (*s == ':' || ((p=strchr(s, '/')) && !memchr(s, ',', p-s))) {
 		if (*s == ':') s++;
 		if (*s == '/' || *s == '.') {
-			if (!libc.secure || !strcmp(s, "/etc/localtime"))
+			if (!libc.secure || !strcmp(s, "/system/etc/localtime"))
 				map = __map_file(s, &map_size);
 		} else {
 			size_t l = strlen(s);
@@ -168,6 +185,7 @@
 			}
 		}
 		if (!map) s = __gmt;
+	}
 	}
 	if (map && (map_size < 44 || memcmp(map, "TZif", 4))) {
 		__munmap((void *)map, map_size);

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-22  2:37             ` Рысь
@ 2015-01-31 15:08               ` Рысь
  2015-02-03  5:52                 ` Rich Felker
  0 siblings, 1 reply; 18+ messages in thread
From: Рысь @ 2015-01-31 15:08 UTC (permalink / raw)
  To: musl

В Thu, 22 Jan 2015 09:37:52 +0700
Рысь <lynx@sibserver.ru> пишет:

> В Wed, 21 Jan 2015 13:36:37 -0500
> Rich Felker <dalias@libc.org> пишет:
> 
> > It would be very much appreciated to send patches as attachments
> > rather than links. There's no way to have a well-documented ongoing
> > discussion of the patch if it's not in a permanent place for review,
> > and attached to the email/archives is the best way to achieve that.
> > 
> > Rich
> 
> Sorry.
> 
> Now patch is attached (I think it is more sane now to include it here)

No comments about code correctness and security?

That patch I sent to list contains a typo in android_isappusr(): return
(p != 0) instead of (p == 0).

The code works fine on my phone for now, I moved all bionic depend
binaries to patched musl without pain. Thanks for your useful hints.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: musl and android
  2015-01-31 15:08               ` Рысь
@ 2015-02-03  5:52                 ` Rich Felker
  0 siblings, 0 replies; 18+ messages in thread
From: Rich Felker @ 2015-02-03  5:52 UTC (permalink / raw)
  To: musl

On Sat, Jan 31, 2015 at 10:08:56PM +0700, Рысь wrote:
> В Thu, 22 Jan 2015 09:37:52 +0700
> Рысь <lynx@sibserver.ru> пишет:
> 
> > В Wed, 21 Jan 2015 13:36:37 -0500
> > Rich Felker <dalias@libc.org> пишет:
> > 
> > > It would be very much appreciated to send patches as attachments
> > > rather than links. There's no way to have a well-documented ongoing
> > > discussion of the patch if it's not in a permanent place for review,
> > > and attached to the email/archives is the best way to achieve that.
> > > 
> > > Rich
> > 
> > Sorry.
> > 
> > Now patch is attached (I think it is more sane now to include it here)
> 
> No comments about code correctness and security?

I haven't yet had a chance to look in detail. I just read over it
briefly again and one thing that popped out is that some aspects are
not namespace clean. In particular there are standard functions
depending on symbols with names like android_* rather than something
in the reserved namespace like __android_*.

One other thing that struck me was all the __istonum functions. The
need for separate functions for all those things seems to be an
artificial creation due to a bad calling convention -- using a
pointer-to-result as the argument. If you instead returned the value
and used a pointer-to-error-flag as the argument, one function would
suffice for all integer types.

In general I suspect there's still more that could be streamlined or
where the size of the diff versus upstream could be reduced.

I didn't see any other glaring security or correctness issues but I'll
let you know if I notice another when I get a chance to read it in
more detail.

> That patch I sent to list contains a typo in android_isappusr(): return
> (p != 0) instead of (p == 0).
> 
> The code works fine on my phone for now, I moved all bionic depend
> binaries to patched musl without pain. Thanks for your useful hints.

Nice!

Rich


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2015-02-03  5:52 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-15  9:13 musl and android Рысь
2015-01-15 11:01 ` Rich Felker
2015-01-15 12:00   ` dynamic linking (Re: [musl] musl and android) u-wsnj
2015-01-15 12:15     ` Rich Felker
2015-01-15 13:04       ` u-wsnj
2015-01-15 13:34         ` Rich Felker
2015-01-15 15:56           ` OT: " u-wsnj
2015-01-15 13:53   ` musl and android Рысь
2015-01-18  6:32 ` Рысь
2015-01-18  6:44   ` Rich Felker
2015-01-18  8:01     ` Рысь
2015-01-18 16:40       ` Rich Felker
2015-01-19 18:00         ` Рысь
2015-01-21 10:34         ` Рысь
2015-01-21 18:36           ` Rich Felker
2015-01-22  2:37             ` Рысь
2015-01-31 15:08               ` Рысь
2015-02-03  5:52                 ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).