Skip to content

ENT-14145: Fixed GlobFind walks unrelated parents of literal path components#273

Merged
nickanderson merged 1 commit into
NorthernTechHQ:masterfrom
nickanderson:ENT-14146/master
Jun 2, 2026
Merged

ENT-14145: Fixed GlobFind walks unrelated parents of literal path components#273
nickanderson merged 1 commit into
NorthernTechHQ:masterfrom
nickanderson:ENT-14146/master

Conversation

@nickanderson
Copy link
Copy Markdown
Contributor

@nickanderson nickanderson commented May 28, 2026

GlobFind() handed every absolute pattern to PathWalk("/", ...), which enumerated and stat'd every entry of each parent directory on the way down — even when the path components were literal with no glob metacharacters. Relative patterns did the same thing rooted at ..

For a pattern like /var/cfengine/state/diff/*.diff, you'd get opendir("/") + getdents + stat on every top-level entry of / before the walk ever reached /var. When one of those top-level entries is a stale NFS mount, newfstatat blocks indefinitely in rpc_wait_bit_killable and the whole process wedges in uninterruptible D state. cf-execd then spawns a new cf-promises every cycle, each of which also wedges — the pile-up the customer reported on ENT-14146.

To fix:

Peel literal components (no *, ?, [, ]) off the front of the component sequence and start PathWalk() at the deepest literal directory. For /var/cfengine/state/diff/*.diff the walk becomes:

stat("/var") -> stat("/var/cfengine") -> stat("/var/cfengine/state") -> stat("/var/cfengine/state/diff")
opendir("/var/cfengine/state/diff") + getdents + match *.diff

It never touches /dev, /proc, or any unrelated top-level entry. Same logic now applies to relative patterns — a/b/c/*.txt opens only ./a/b/c, never ./a/d or ./a/sibling.txt.

The peel lives in GlobFind() (not PathWalk()) because that's where the component sequence is known. PathWalk() stays general-purpose.

Not covered:

  • Escaped glob metacharacters (\*, \?). IsGlobLiteral is conservative — sees the *, returns false, falls back to the existing PathWalk + GlobMatch flow which does honor the escape.
  • Windows network paths (\\host\...) and disk paths (C:\...) are unchanged.

Ticket: ENT-14146

@mender-test-bot
Copy link
Copy Markdown

There was an error running your pipeline, see logs for details.

@nickanderson nickanderson marked this pull request as draft May 28, 2026 17:28
Comment thread libutils/glob_lib.h.in Outdated
@nickanderson nickanderson force-pushed the ENT-14146/master branch 2 times, most recently from 6be4366 to 43b5ecf Compare May 28, 2026 18:24
@nickanderson nickanderson marked this pull request as ready for review May 28, 2026 18:25
@mender-test-bot
Copy link
Copy Markdown

There was an error running your pipeline, see logs for details.

@nickanderson
Copy link
Copy Markdown
Contributor Author

@cf-bottom jenkins please?

@cf-bottom
Copy link
Copy Markdown

cf-bottom commented May 28, 2026

@nickanderson nickanderson requested a review from larsewi May 28, 2026 19:30
Copy link
Copy Markdown
Contributor

@larsewi larsewi left a comment

Choose a reason for hiding this comment

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

So stat can cause program to block on NFS. Didn't know that.

GJ 🚀 added some comments

Comment thread libutils/glob_lib.c Outdated
Comment thread libutils/glob_lib.h.in Outdated
Comment thread tests/unit/glob_lib_test.c Outdated
@mender-test-bot
Copy link
Copy Markdown

There was an error running your pipeline, see logs for details.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 29, 2026

CLA assistant check
All committers have signed the CLA.

@mender-test-bot
Copy link
Copy Markdown

There was an error running your pipeline, see logs for details.

@mender-test-bot
Copy link
Copy Markdown

There was an error running your pipeline, see logs for details.

@mender-test-bot
Copy link
Copy Markdown

There was an error running your pipeline, see logs for details.

@mender-test-bot
Copy link
Copy Markdown

There was an error running your pipeline, see logs for details.

@nickanderson
Copy link
Copy Markdown
Contributor Author

@cf-bottom jenkins please?

@cf-bottom
Copy link
Copy Markdown

@nickanderson nickanderson requested a review from larsewi June 1, 2026 14:32
GlobFind() handed every absolute pattern to PathWalk("/", ...), which calls
ListDir() + stat() on every entry of each parent directory on the way down.
For a pattern like /var/cfengine/state/diff/*.diff this enumerates and stats
every entry of /, every entry of /var, and every entry of /var/cfengine
before reaching the target directory.

When any top-level entry under / is on a stale NFS mount, the kernel-side
getattr RPC blocks indefinitely in rpc_wait_bit_killable. cf-promises (and
any binary that loads policy via libpromises) enters uninterruptible D state
and cannot be killed until the mount is force-unmounted or the server
returns. cf-execd then spawns a new cf-promises on every cycle, each of
which also wedges, producing the process pile-up reported in ENT-14146.

Peel literal components (no glob metacharacters) off the front of the
component sequence and start PathWalk at the deepest literal directory.
For /var/cfengine/state/diff/*.diff the walk becomes stat("/var") ->
stat("/var/cfengine") -> stat("/var/cfengine/state") ->
stat("/var/cfengine/state/diff") -> opendir("/var/cfengine/state/diff") +
getdents + match *.diff, and never touches unrelated top-level entries.

Ticket: ENT-14146
Changelog: Title
@mender-test-bot
Copy link
Copy Markdown

There was an error running your pipeline, see logs for details.

@nickanderson nickanderson merged commit 944af92 into NorthernTechHQ:master Jun 2, 2026
6 checks passed
@nickanderson nickanderson changed the title Fix: GlobFind walks unrelated parents of literal path components (ENT-14146) ENT-14145: Fixed GlobFind walks unrelated parents of literal path components Jun 2, 2026
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.

5 participants