Disable NSS modules when using the leakchecker

The leakchecker will report leaked file descriptors when tests do things
like access `Etc.getgrgid`, for example, if NSS modules (like `sss`)
handle these lookups by connecting to a daemon like `sssd` and leave the
connection open.

To address this, we can call glibc's `__nss_configure_lookup` to
override NSS modules configured in /etc/nsswitch.conf and only use
ordinary file/DNS lookups.

(This is a cherry-pick of a patch applied to ruby/mspec here:
https://github.com/ruby/mspec/pull/62)
This commit is contained in:
KJ Tsanaktsidis 2024-01-22 09:13:35 +11:00 committed by KJ Tsanaktsidis
parent 0fadac4c7d
commit 33290896dc

View File

@ -301,6 +301,7 @@ class LeakCheckerAction
end
def start
disable_nss_modules
@checker = LeakChecker.new
end
@ -316,4 +317,58 @@ class LeakCheckerAction
end
end
end
private
# This function is intended to disable all NSS modules when ruby is compiled
# against glibc. NSS modules allow the system administrator to load custom
# shared objects into all processes using glibc, and use them to customise
# the behaviour of username, groupname, hostname, etc lookups. This is
# normally configured in the file /etc/nsswitch.conf.
# These modules often do things like open cache files or connect to system
# daemons like sssd or dbus, which of course means they have open file
# descriptors of their own. This can cause the leak-checking functionality
# in this file to report that such descriptors have been leaked, and fail
# the test suite.
# This function uses glibc's __nss_configure_lookup function to override any
# configuration in /etc/nsswitch.conf, and just use the built in files/dns
# name lookup functionality (which is of course perfectly sufficient for
# running ruby/spec).
def disable_nss_modules
begin
require 'fiddle'
rescue LoadError
# Make sure it's possible to run the test suite on a ruby implementation
# which does not (yet?) have Fiddle.
return
end
begin
libc = Fiddle.dlopen(nil)
nss_configure_lookup = Fiddle::Function.new(
libc['__nss_configure_lookup'],
[Fiddle::Types::CONST_STRING, Fiddle::Types::CONST_STRING],
Fiddle::Types::INT
)
rescue Fiddle::DLError
# We're not running with glibc - no need to do this.
return
end
nss_configure_lookup.call 'passwd', 'files'
nss_configure_lookup.call 'shadow', 'files'
nss_configure_lookup.call 'group', 'files'
nss_configure_lookup.call 'hosts', 'files dns'
nss_configure_lookup.call 'services', 'files'
nss_configure_lookup.call 'netgroup', 'files'
nss_configure_lookup.call 'automount', 'files'
nss_configure_lookup.call 'aliases', 'files'
nss_configure_lookup.call 'ethers', 'files'
nss_configure_lookup.call 'gshadow', 'files'
nss_configure_lookup.call 'initgroups', 'files'
nss_configure_lookup.call 'networks', 'files dns'
nss_configure_lookup.call 'protocols', 'files'
nss_configure_lookup.call 'publickey', 'files'
nss_configure_lookup.call 'rpc', 'files'
end
end