On Sun, May 05, 2019 at 06:49:30PM -0600, Jerry James wrote:
Awhile back, I mentioned that GCL was building in mock on my local
machine, but was segfaulting on the koji builders. By dint of much
experimentation, I now know what is going on. For the enlightenment
of anybody who cares:
- GCL is linked with libtirpc.
- libtirpc is linked with libselinux.
- libselinux has a "constructor" function, init_lib(), that runs before
main().
- init_lib() calls init_selinuxmnt()
- init_selinuxmnt() checks that /sys/fs/selinux exists, has type
SELINUX_MAGIC (see statfs(2)), and is not read-only. In mock on my
home machine, all of this is true, so execution stops there; the
library is initialized.
- On the koji builders, /sys/fs/selinux does exist, but is read-only,
so it fails the test. The code then does the same check on /selinux,
but that doesn't exist. Due to both failures, selinuxfs_exists() is
called to see if the running kernel even knows about selinuxfs.
- selinuxfs_exists() walks through the contents of /proc/filesystems.
That walk involves calls to getline(), which calls malloc(), and
free().
- GCL has its own definitions of malloc() and free(), but those
definitions require that address randomization be turned off. GCL
accomplishes this with a call to personality() early in main(), but
the libselinux initializer runs before main(), resulting in GCL
segfaulting in free().
So the issue isn't really mock on my machine vs. koji: it is systems
where /sys/fs/selinux is mounted read-write versus those where it is
mounted read-only or not mounted at all.
One workaround is to invoke GCL at build time with setarch -R gcl
<args>, but that means any GCL users who do not have /sys/fs/selinux
mounted read-write will have to do the same.
In the RPM build, move the real 'gcl' binary to /usr/libexec.
Then create a /usr/bin/gcl that is just a shell script that
invokes "setarch -R gcl /usr/libexec/gcl $@".
Though as Florian suggests, the better solution is to not have
the personality() call in main - have it called by malloc(), or
possibly a constructor function that's part of the object
providing the malloc replacement.
Regards,
Daniel
--
|:
https://berrange.com -o-
https://www.flickr.com/photos/dberrange :|
|:
https://libvirt.org -o-
https://fstop138.berrange.com :|
|:
https://entangle-photo.org -o-
https://www.instagram.com/dberrange :|