Subject: kern/33375: compat_30_sys_getdents sees only top layer of union on -current
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <chap@NetBSD.org>
List: netbsd-bugs
Date: 04/27/2006 05:45:00
>Number:         33375
>Category:       kern
>Synopsis:       compat_30_sys_getdents sees only top layer of union on -current
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 27 05:45:00 +0000 2006
>Originator:     Chapman Flack
>Release:        3.99.18
>Organization:
>Environment:
NetBSD 3.99.18 NetBSD 3.99.18 (olaf) #4: Mon Apr 24 17:00:37 EDT 2006 xxx@xxx:/usr/src/sys/arch/i386/compile/olaf i386
>Description:
If a union mount is created on a system running -current, 3.0 binaries that call the compat_30 version of getdents(2) can only see entries that are present in the top layer of the union.  They can stat/open/read/write any entry in the union if they know the name, but if it isn't in the top layer they cannot see it.

This may seem like an unlikely scenario, but it comes up naturally
enough in using pkgtools/pkg_comp-like techniques to build 3.0 binaries
on a -current box.
>How-To-Repeat:
Assume a 3.0 /bin and /lib are extracted in /30root

# mkdir t0 t1
# >t0/aaa >t0/bbb
# mount_union t1 t0
# ls t0
aaa bbb
# LD_PRELOAD=/30root/lib/libc.so /30root/bin/ls t0
#

Without the LD_PRELOAD, the files will be seen. The difference is
that the old libc calls the (now) compat_30 getdents(2), while the
new libc calls the current getdents, which seems to work.
>Fix:
Partial workaround: when preparing a 3.0 environment to chroot into,
make the *current* ld.elf_so visible in its /libexec, and the
*current* libc.so* visible in its /lib.  This should cause any of the
dynamically-linked 3.0 binaries that use readdir to be linked with
the current libc and therefore to invoke the current getdents(2).
I've confirmed that 'ls' in the chroot environment properly shows all
entries when this is done.  (Of course the second or third 'ls' incurs
kern/33374, but that seems to be a separate problem--it's repeatable
using only native 3.99 binaries and no chroot. That limits how useful
this workaround is, but this could be a usable workaround once that is
fixed.)

Real fix: teach compat_30_sys_getdents to correctly enumerate entries in unions.  (No clue how much trouble that should be.)