Skip to content

Read ld.so.conf the way ldconfig reads it - #2130

Open
v0ropaev wants to merge 1 commit into
NVIDIA:mainfrom
v0ropaev:fix/ldsoconf-parse
Open

v0ropaev wants to merge 1 commit into
NVIDIA:mainfrom
v0ropaev:fix/ldsoconf-parse

Conversation

@v0ropaev

@v0ropaev v0ropaev commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

processLdsoconfFile builds the set of directories the container's ldcache already covers, which is then subtracted from the directories the hook would add. A line it reads differently from ldconfig costs a directory, and the libraries in that directory are not found.

Five differences from parse_conf and parse_conf_include in glibc's elf/ldconfig.c:

Trailing comments. ldconfig ends every line at the first #, because the format has no quoting:

/* Because the file format does not know any form of quoting we
   can search forward for the next '#' character and if found
   make it terminating the line.  */
*strchrnul (line, '#') = '\0';

Here only a line starting with # was skipped, so /usr/local/lib # vendor libs became a directory of that whole name, and the same comment after an include left the pattern matching nothing.

A tab after include. The test was strings.HasPrefix(line, "include "); ldconfig accepts any blank (isblank (cp[7])). With a tab the line fell through and became a directory.

More than one pattern. ldconfig splits the remainder on blanks and globs each one:

cp += 8;
while ((dir = strsep (&cp, " \t")) != NULL)
  if (dir[0] != '\0')
    parse_conf_include (filename, lineno, do_chroot, dir);

The whole remainder went to a single filepath.Glob, and a pattern with a space in it matches nothing, so all of the patterns were lost rather than just the later ones.

Relative include patterns. ldconfig resolves them against the directory of the file that holds them:

if (pattern[0] != '/' && strchr (config_file, '/') != NULL)
  asprintf (&copy, "%s/%s", dirname (strdupa (config_file)), pattern);

filepath.Glob resolved them against the working directory. This runs after the pivot into the container root, so include ld.so.conf.d/*.conf in /etc/ld.so.conf looked for /ld.so.conf.d/*.conf.

hwcap lines. They became directories. ldconfig has ignored the directive since 2.33 and only reports it.

The TODO: How does ldconfig handle this? on the ErrBadPattern path is answered in a comment: a malformed pattern is no match and parsing carries on, which is what the code already did.

Tests

TestProcessLdsoconfFile, table-driven over a temporary directory, covering each of the five plus the cases that already worked, which are there as regression guards: a whole-line comment, an absolute include, a line that only looks like a directive (include alone, /includes, /hwcapsomething), and an include that matches nothing.

Six of the ten subtests fail on main, each with the wrong value from above. go test ./internal/... passes, go vet and gofmt clean.

processLdsoconfFile decides which directories the container's ldcache already
covers, so a line it reads differently from ldconfig costs a directory, and
the libraries in it are not found. Five differences, against parse_conf and
parse_conf_include in glibc's elf/ldconfig.c:

- a trailing comment stayed on the line. ldconfig ends every line at the
  first '#', the format has no quoting; here only a line that started with
  one was skipped, so "/usr/local/lib # vendor libs" became a directory of
  that whole name, and the same comment on an include left it matching
  nothing
- "include" followed by a tab was not a directive, since the prefix tested
  for was "include "; ldconfig takes any blank, so the line became a
  directory instead
- only the first pattern of an include was used: ldconfig splits the
  remainder on blanks and globs each one, while the whole remainder went to
  one Glob call, which a pattern with a space in it cannot match
- a relative include resolved against the working directory. ldconfig
  resolves it against the directory of the file that holds it, so after the
  pivot into the container root "include ld.so.conf.d/*.conf" looked for
  /ld.so.conf.d/*.conf rather than /etc/ld.so.conf.d/*.conf
- a hwcap line became a directory; ldconfig has ignored the directive since
  2.33 and only reports it

Also answers the TODO on the ErrBadPattern path: ldconfig treats a malformed
pattern as no match and carries on, which is what this already did.

Signed-off-by: Dmitry Voropaev <dy.voropaev@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Oct 8, 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.

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.

1 participant