ftpd authentication [PATCH] ftpd: NOMMU/chroot fix

Denys Vlasenko vda.linux at googlemail.com
Thu Jun 26 08:52:01 UTC 2014


On Thu, Jun 26, 2014 at 9:27 AM, Morten Kvistgaard
<MK at pch-engineering.dk> wrote:
> Here's how to reproduce the error:
>
> I'm using a i386 Ubuntu 10.04.
>
> - Enable the "Force NOMMU build" in menuconfig. (Also make sure the ftpd is added.)
> - Add the busybox ftpd to your inetd. Something like:
>
> ftp     stream  tcp     nowait  root    /home/mk/workspace/busybox/busybox      busybox ftpd -w /home/
>
> - The important part is the jail dir. Eg. "/home/". Whatever. Make sure it has a file or two. (And reload your inetd.)
> - Open your favorite ftp client against the server. I'm using WinSCP, FileZilla or win32 ftp.
> - If the ftp client can list your files, then all is good. (Mine cannot.)

Mine works. Here's what strace shows:

execve("./busybox", ["./busybox", "ftpd", "/home"], [/* 53 vars */]) = 0
...
...
read(0, "LIST\r\n", 4096)               = 6
getcwd("/", 192)                        = 2
pipe([5, 6])                            = 0
vfork()                                 = 21778

The vfork'ed child does this:

fchdir(3)                               = 0
close(5)                                = 0
dup2(6, 1)                              = 1
close(6)                                = 0
close(0)                                = 0
dup(1)                                  = 0
execve("proc/self/exe", ["ftpd", "-l", "/"], [/* 46 vars */]) = 0
<--snip unimportant syscalls-->
chdir("/")                              = 0
<--snip unimportant syscalls-->
lstat64(".", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY) = 3
fstat(3, {st_mode=S_IFIFO, st_size=3210253738927550530, ...}) = 0
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
brk(0x9554000)                          = 0x9554000
getdents64(3, /* 35 entries */, 4096)   = 1600

As you see, argv[2] of the helper is "/",
and since helper is still chroot'ed to /home,
when it executes this xchdir("/"):

        if (opts & (OPT_l|OPT_1)) {
                /* Our secret backdoor to ls */
                xchdir(argv[2]);   <-------------------- HERE
                argv[2] = (char*)"--";
                /* memset(&G, 0, sizeof(G)); - ls_main does it */
                return ls_main(argc, argv);
        }

it ends up exactly in /home, and will list its files.


> The problem lies in the "exit jail" under the NO_MMU part.

Sorry.
I don't understand your bug description, you need to be more verbose.


More information about the busybox mailing list