Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 8 Jun 2016 13:50:32 -0400
From: Rich Felker <>
Subject: Re: realpath() depends on a mounted /proc to work

On Tue, Jun 07, 2016 at 08:45:21AM +0300, Timo Teras wrote:
> On Mon, 6 Jun 2016 21:15:39 -0400
> Rich Felker <> wrote:
> > On Tue, Jun 07, 2016 at 08:27:18AM +0800, Lei Zhang wrote:
> > > Hi,
> > > 
> > > I observed that realpath() doesn't work correctly without a mounted
> > > /proc while experimenting in a chroot system, where musl is the
> > > default libc. OTOH, the same program statically linked against glibc
> > > worked just as expected.
> > > 
> > > Is the dependence on a mounted /proc intentional? Then what's the
> > > rationale behind it?  
> > 
> > As a whole, musl depends on having /proc; the rationale is simply that
> > Linux does not expose all the functionality needed to implement POSIX
> > without /proc.
> > 
> > As for realpath, it could be done without /proc, but being that musl
> > already requires /proc for full functionality, and that non-/proc
> > versions of realpath are significantly heavier, more complex, and less
> > reliable, simply using /proc for realpath was the natural choice.
> > 
> > If someone wants to do a survey of what functionality actually depends
> > on /proc, we could document that and also evaluate whether realpath is
> > sufficiently more "basic" than other things which need /proc that we
> > might want to consider having a fallback implementation for when /proc
> > is missign.
> I remember we discussed this earlier, as I would prefer to have it for
> running scripts in chroot from alpine package manager (without /proc).
> This would also fix applications that chroot to isolated place after
> startup (e.g. some ftp servers).
> Grep says /proc is found to be used in:
>  - __synccall - /proc/self/task
>  - __procfdname - to generate /proc/self/fd/%d
>  - dl_iterate_phdr - /proc/self/exe as name for main executable
>  - dynlink - for $ORIGIN (and filtering it out from AT_EXECFN)
> __synccall is used basically for setrlimit() and set*uid(). These
> generally are done in the application startup, but could become issue
> in chrooted multi-threaded programs.
> And __procfdname is used in:
>  - ttyname_r
>  - realpath
>  - fexecve
>  - fchdir
>  - fchown
>  - fstat
>  - fchmodat
>  - fchmod
> For these fexecve, ttyname_r and realpath seem to unconditionally
> depend on it. For the other f* fd functions it is only the fallback
> code for really old kernels.

This is not quite true. As of at least 3.18 or so, Linux did not
support most of the f* ops (fstat, fchdir, etc.) on O_PATH file
descriptors; it may still lack support. Also the Linux fchmodat
syscall completely lacks the flag argument (contrary to musl's useless
passing of it) so /proc is unconditionally required to support
fchmodat with nonzero flag.

> Given the above, I would vote realpath() to have fallback code. It's
> far more widely used, and would fix several chroot usage scenarios.

That seems reasonable. Fallback code should avoid using significant
additional stack space and should probably only be used if the proc
version fails with ENOENT (proc not mounted) and not on transient
errors, so that it doesn't become a bug surface that could affect
properly configured systems under low-resource conditions.

> Btw, one discrepency is that ttyname_r declares:
> 	char procname[sizeof "/proc/self/fd/" + 3*sizeof(int) + 2];
> and all other users:
> 	char buf[15+3*sizeof(int)];
> ttyname_r this allocates one more byte for the buffer and makes it
> clear where that size comes from. Perhaps this would be good place for
> some internal header that has #define and prototype for __procfdname.

Yes that might be a good idea. BTW I think it's 2 more bytes, not 1.


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.