svn commit: r228843 - head/contrib/telnet/libtelnet head/crypto/heimdal/appl/telnet/libtelnet head/include head/lib/libc/gen head/lib/libc/iconv head/lib/libc/include head/lib/libc/net head/libexec...

John Baldwin jhb at
Thu Dec 29 21:21:05 UTC 2011

On Thursday, December 29, 2011 3:30:23 pm Xin Li wrote:
> On 12/29/11 11:35, John Baldwin wrote:
> > On Thursday, December 29, 2011 2:10:37 pm Xin LI wrote:
> >> On Thu, Dec 29, 2011 at 11:00 AM, John Baldwin <jhb at>
> >> wrote:
> >>> On Thursday, December 29, 2011 1:44:01 pm Xin Li wrote:
> >>>> On 12/29/11 10:43, John Baldwin wrote:
> >>>>> On Thursday, December 29, 2011 1:26:17 pm Xin Li wrote:
> >>>>>> On 12/29/11 06:39, John Baldwin wrote:
> >>>>>>> Can you give some more details on why ftpd is
> >>>>>>> triggering a dlopen inside of the chroot?  It would
> >>>>>>> appear that that is unrelated to helper programs (since
> >>>>>>> setting a flag in libc in ftpd can't possibly affect
> >>>>>>> helper programs ability to use dlopen() from within
> >>>>>>> libc).
> >>>>>>
> >>>>>> Sure.  That's because nsdispatch(3) would reload
> >>>>>> /etc/nsswitch.conf if it notices a change.  After
> >>>>>> chroot() the file is considered as "chang"ed and thus it
> >>>>>> reloads the file as well as designated shared libraries.
> >>>>>
> >>>>> But ftpd has to be doing some operation that invokes an nss
> >>>>> lookup after entering the chroot for that to trigger,
> >>>>> correct?
> >>>>
> >>>> Oh ok, that was the built-in ls(1).
> >>>
> >>> Were we not able to drop privilege before doing that?  I.e. if
> >>> you forked a new process that dropped privilege before doing
> >>> the ls (similar to if you were to exec /bin/ls as a helper),
> >>> would that not have fixed this?
> >>
> >> No, it won't.  This is arbitrary code execution and not just
> >> privilege escalation :(
> >
> > So how is there not still a problem for helper programs?  Is ls the
> > only way a user can initiate a helper program?  Hmm, looks like
> > ftpd will only ever invoke ls, and thus only ls_main(), so there's
> > lots of dead code (e.g. where ftpd invokes execv() in ftpd_popen()
> > is a dead code path).  That clears up some confusion on my part as
> > I didn't understand why it was ok to execute arbitrary programs
> > from ftpd but the built-in ls was special.  I still find the symbol
> > name incredibly ugly.  Another route might have been set an env
> > var
> It is ugly.
> > to disable use of dlopen() in libc.  That would have worked even if
> > ftpd invoked an external program, whereas the built-in ls is now
> > key to security and no longer a simple optimization.
> I think it's not an optimization but how ftpd would work in chroot
> environment without a partial or full blown FreeBSD inside chroot
> setup?  Otherwise one will not be able to do 'ls' if user was chroot.

Presumably one could do a static ls.  Even with the built-in ls we
create a dummy passwd/group file for the anonymous chroot by default.
I agree a built-in ls is strictly better, however.  I would also be
fine with removing all notion of execv for helper programs from ftpd
and have it only ever use the built-in ls via ftpd_popen().

> Using an environment variable may be not a good idea since it can be
> easily overridden, and I think if the program runs something inside
> the chroot, the jailed chroot would have more proper setup to avoid
> this type of attack?

Well, it would not be possible to override it in the immediate process
being executed.  Right now that case is not handled at all.  However,
I do think that this mostly falls down to creating "safe" chroot / jail
areas rather than the OS being able to defend unsafe areas.

John Baldwin

More information about the freebsd-security mailing list