[Rpm-maint] [PATCH] fix loading NSS libraries prior to chrooting

Thierry Vignaud thierry.vignaud at gmail.com
Fri Apr 5 14:32:21 UTC 2013

On 5 April 2013 08:00, Panu Matilainen <pmatilai at laiskiainen.org> wrote:
>> rpm preloads NSS  libraries prior to chrooting in order to
>> fix group lookup in the chroot (when installing in a chroot):
>> lib/rpmrc.c-    /* Force preloading of dlopen()'ed libraries in case
>> we go chrooting */
>> lib/rpmrc.c:    (void) gethostbyname("localhost");
>> However in some cases, this is not enough.
>> See https://bugs.mageia.org/show_bug.cgi?id=9326
>> Strace showed that in some case, it tries to load libnss*so
>> after chrooting, way too late, resulting in borked installs.
> Do you have a strace of such a situation still at hand / can you easily
> reproduce one?

Yes I can easily reproduce it.

> Just interested to see what's going on in such a case, not
> that I couldn't imagine things failing in some circumstances: for example if
> the system nsswitch.conf specifies hosts to come from a different source
> than passwd/group.

you know well we use urpmi as our package manager with perl-URPM
as the perl binding for rpm.
urpmi is used by our installer (drakx) too.
Drakx is a little bit like anaconda, a small stage1 loading a full stage2
(a minimal system that will offer to select options and then install the
targeted system) that intalls in a chroot (/mnt in drakx vs /mnt/sysimage
in anaconda).

There's a special case, where we can run our installer directly from a running
system, either for debugging or in order to generate a live cd image,
unsing a tool named drakx-in-chroot.

It basically sets up a chroot for the installer, copies a score of
files (a cople
/dev/ entries, /etc/resolv.conf) and tells the installer it has to run
in local mode
(no partitionning and the like).
Basically we've:
running OS -> chroot installer system -> installs in a chroot.

When run in graphical (Gtk+) mode, everything worked fine.
However, in auto install mode, we found out that group ownership wasn't
enforced (see above bug #9326).
It was reproductable in text mode too.
In the end I found out that as part of it initiliazition gtk+/libx11 was loading
some NSS files.

When they were not previously loaded, on first translation, rpm installs
glibc+setup+filesystem (+a cople other packages), thus having
a minimal /etc/group (later packages adding their needed groups when
needed if needed).
The first time, librpm saw a non root group, it tries to load NSS
libraries, which
obviously fails since it's now chrooted in the being installed OS (see
attached strace diff).
In auto install mode, all transactions where some packages use non a root group
shows errors (see install.log.diff):

+group daemon does not exist - using root
+group mail does not exist - using root

Obviously this worked previously (up to rpm-4.9 that was used in Mageia2),
so either something broke in librpm or some other library was causing NSS libs
to be loaded before chrooting.

See attached extract diff of two strace "sessions"

Here, we can workarounding this either by:
- making NSS libs to be loaded from perl before performing the install
in a chroot
- or by not copying /etc/resolv.conf in the install chroot (which would
  prevent us to use remote media)
- or by patching rpm to really always preload NSS libs

But I don't think forcing NSS libs to be loaded is the job of the librpm users,
hence the rpm patch.
For the record, we do hit rpmReadConfigFiles() before chrooting...

>> The following patch makes rpm to really force preloading of
>> dlopen()'ed libraries before chrooting
>> Patches against master & rpm-4.11.x
>> Please apply.
> It probably should actually call getpwent() as well for full coverage
> against nsswitch.conf variants. And then the gethostbyname() call becomes
> unnecessary as we're not interested in hosts, the whole thing is nothing but
> a cheap trick that "works" most of the time.
> However I seem to recall glibc caching the passwd and group contents, so if
> we force it to read passwd and group before chrooting, it might well end up
> using the values from the host system instead of what should go into the
> chroot. At the very least I'd think it should call endgrent() (and endpwent)
> as well.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: strace.diff
Type: application/octet-stream
Size: 1181 bytes
Desc: not available
URL: <http://lists.rpm.org/pipermail/rpm-maint/attachments/20130405/27d0c627/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: install.log.diff
Type: application/octet-stream
Size: 1881 bytes
Desc: not available
URL: <http://lists.rpm.org/pipermail/rpm-maint/attachments/20130405/27d0c627/attachment-0001.obj>

More information about the Rpm-maint mailing list