Skip to content

internal/nvsandboxutils: Look up entry points with dlsym - #2087

Open
rautyrauty wants to merge 2 commits into
NVIDIA:mainfrom
rautyrauty:fix-nvsandboxutils-unresolved-symbols
Open

rautyrauty wants to merge 2 commits into
NVIDIA:mainfrom
rautyrauty:fix-nvsandboxutils-unresolved-symbols

Conversation

@rautyrauty

Copy link
Copy Markdown
Contributor

Description

The generated bindings reference the libnvidia-sandboxutils entry points at link time and link with -Wl,--unresolved-symbols=ignore-in-object-files, so every binary using them keeps five unresolved dynamic symbols, bound
lazily against the library lib.go dlopens with RTLD_GLOBAL.

Two consequences:

  • Distributions that check packages for unresolved ELF symbols reject such binaries on platforms where the library is not packaged at all. This breaks LXD (which vendors pkg/nvcdi) on ALT Linux i586 and aarch64, where nothing
    provides libnvidia-sandboxutils.so.1:
i586: NEW bad_elf_symbols detected:
lxd-6.9-alt1.i586.rpm /usr/bin/lxd U nvSandboxUtilsInit
  • A call made before a successful Init() terminates the process with a dynamic linker symbol lookup error instead of returning a code.

The entry points are now resolved with dlsym(RTLD_DEFAULT) — the same global scope the dynamic linker searched, so a loaded library is found exactly as before, and an absent one yields NVSANDBOXUTILS_ERROR_LIBRARY_LOAD.

The wrappers are a plain .c/.h pair pulled into the preamble via Includes in the c-for-go configuration, so regenerating the bindings keeps them; the generated files change only as that configuration dictates. nvml*
symbols from go-nvml are untouched — the same treatment there would span several hundred generated functions and is better done separately.

Checklist

  • No secrets, sensitive information, or unrelated changes
  • Unit tests passing (make test)
  • Lint checks passing (make lint)
  • Test cases are added for new code paths
  • Commits are signed-off and cryptographically signed

Testing

  • make test passes; golangci-lint run ./internal/nvsandboxutils/... reports 0 issues.
  • nm -D --undefined-only nvidia-ctk | grep nvSandboxUtils: 5 symbols before, 0 after.
  • Manually against a stub libnvidia-sandboxutils.so.1: Init, GetDriverVersion and Shutdown return the stub's values; with no library present Init returns ERROR_LIBRARY_LOAD instead of crashing.
  • Regenerated with c-for-go to confirm the generated preamble and call sites match this diff.
  • Rebuilt the ALT Linux lxd package with these bindings vendored: the repository-wide ELF symbols check, which previously reported five new nvSandboxUtils* symbols, now passes on x86_64, i586 and aarch64, and the resulting
    i586 binary has no unresolved nvSandboxUtils* left.
  • No GPU node was available; the runtime path was exercised with the stub library only.

@copy-pr-bot

copy-pr-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@rajatchopra rajatchopra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useful PR.
Can we have a mock_nvsandbox.so and build a unit test case around the five calls?

This is necessary so that binaries linking these bindings carry no
unresolved dynamic symbols: distributions that check packages for them
reject such binaries on platforms where the library is not packaged at
all, and a call made before Init() succeeds is then terminated by the
dynamic linker instead of returning an error.

The wrappers resolve against RTLD_DEFAULT, which reaches the library
only because it is opened with RTLD_GLOBAL; narrowing those load flags
would leave every entry point unresolvable.

Signed-off-by: Ajrat Makhmutov <rauty@altlinux.org>
…k library

The dynamicLibrary mock stops at the Go boundary and cannot cover the
dlsym wrappers, so this builds a real shared object at test time and
loads it through the normal path. Calling an entry point before the
library is loaded is checked too: that is the case that used to jump
to a NULL address.

Signed-off-by: Ajrat Makhmutov <rauty@altlinux.org>
@rautyrauty
rautyrauty force-pushed the fix-nvsandboxutils-unresolved-symbols branch from 31ab95f to 2e75bad Compare September 22, 2026 13:21
@rautyrauty

Copy link
Copy Markdown
Contributor Author

Added in a follow-up commit: testdata/mock_nvsandbox.c is compiled and dlopen'ed by the test, so all five entry points go through the real dlsym path - on main it fails with undefined symbol: nvSandboxUtilsShutdown.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants