Skip to content

Bug 5554: Cap absurd inherited RLIMIT_NOFILE - #2483

Open
mxschmitt wants to merge 1 commit into
squid-cache:masterfrom
mxschmitt:fix/inherited-nofile-cap
Open

Bug 5554: Cap absurd inherited RLIMIT_NOFILE#2483
mxschmitt wants to merge 1 commit into
squid-cache:masterfrom
mxschmitt:fix/inherited-nofile-cap

Conversation

@mxschmitt

@mxschmitt mxschmitt commented Aug 26, 2026

Copy link
Copy Markdown

Bug 5554: Squid can allocate huge memory from RLIMIT_NOFILE

Bug report: https://bugs.squid-cache.org/show_bug.cgi?id=5554

When Squid starts in a Kubernetes/containerd environment, it may inherit
an absurdly large RLIMIT_NOFILE soft limit (for example 1073741816).
Squid currently uses that value as Squid_MaxFD and eagerly allocates
several descriptor-sized tables during startup. The result is
approximately 536-568 GiB of virtual memory, high CPU, and an
OOM/unusable process before it can serve requests.

The same behavior reproduces with current Squid master (8.0.0-VCS) in an
empty Kubernetes pod. The packaged Squid 7.6 image reproduces it as
well. Outside Kubernetes, with a normal descriptor limit, the same image
starts normally.

Relevant allocation path:

  • setMaxFD() assigns Squid_MaxFD from the inherited RLIMIT_NOFILE.
  • fde::Init() allocates xcalloc(Squid_MaxFD, sizeof(fde)).
  • Comm::MakeCallbackTable() allocates another descriptor-sized table.
  • The later SQUID_MAXFD_LIMIT clamp occurs after these allocations.

This patch caps an inherited default above SQUID_MAXFD before those
allocations and emits a warning. Explicit max_filedescriptors
configuration remains honored, including values above SQUID_MAXFD where
supported.

Before:
RLIMIT_NOFILE=1073741816
VmSize approximately 562-595 GB
pod becomes unusable/OOMs

After:
warning reports the inherited limit and the 32768 cap
VmSize approximately 38 MB
VmRSS approximately 20 MB
pod remains Running

An explicit max_filedescriptors 1048576 regression check remains
honored.

Testing:

  • Built current Squid master on Linux ARM64.
  • Reproduced the failure in Kubernetes/containerd.
  • Rebuilt with this patch and verified normal startup and memory usage
    in the same pod.
  • Verified explicit max_filedescriptors behavior.
  • git diff --check passes.

@squid-anubis squid-anubis added the M-failed-description https://github.com/measurement-factory/anubis#pull-request-labels label Aug 26, 2026
@squid-anubis

This comment was marked as resolved.

@squid-anubis

This comment was marked as resolved.

@mxschmitt
mxschmitt force-pushed the fix/inherited-nofile-cap branch from 7f6d150 to 3ad247b Compare August 26, 2026 00:54
@squid-anubis

This comment was marked as resolved.

@mxschmitt
mxschmitt force-pushed the fix/inherited-nofile-cap branch from 3ad247b to c041695 Compare August 26, 2026 00:56
@squid-anubis squid-anubis removed the M-failed-description https://github.com/measurement-factory/anubis#pull-request-labels label Aug 26, 2026
Comment thread src/tools.cc
return result;
}
#endif // _SQUID_WINDOWS_ || _SQUID_MINGW_

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.

Please restore the empty line at the end of the file.
Apart from this, looks good to me!

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.

Please restore the empty line at the end of the file.

I will fix this while working on the adjustments mentioned in another change request.

@kinkie kinkie added S-waiting-for-author author action is expected (and usually required) backport-to-v7 maintainer has approved these changes for v7 backporting labels Aug 26, 2026

@rousskov rousskov 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.

Bug report: Squid should not blindly trust an absurd inherited soft limit and allocate unbounded descriptor tables before startup completes. It should cap an inherited default to a safe compiled/runtime limit, or otherwise reject it with a clear diagnostic.

Thank you for this bug report and analysis, Max! I agree with the above conclusion and support this PR direction. Some PR changes are required, but I will implement them myself in hope to reduce the number of review iterations and cumulative time spent on this PR. Please stand by -- the ball is in my court.

Since this is your first Squid contribution, I will also add your entry to the CONTRIBUTORS file (unless you stop me).

Comment thread src/tools.cc
// ulimit trigger multi-gigabyte allocations (e.g. Kubernetes may
// provide a billion-descriptor soft limit). This guard runs before
// fde::Init() and Comm callback tables allocate descriptor storage.
if (Config.max_filedescriptors <= 0 &&

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.

This new code deals with so called "inherited" limit, but it is placed into the existing else clause where a non-inherited limit is also tested, necessitating unwanted Config.max_filedescriptors check duplication. The existing code is already messy, but it is easy to avoid making it worse AFAICT.

I will try to adjust this code to avoid this problem. It is easier to do that than to describe that adjustment.

Comment thread src/tools.cc
// provide a billion-descriptor soft limit). This guard runs before
// fde::Init() and Comm callback tables allocate descriptor storage.
if (Config.max_filedescriptors <= 0 &&
rl.rlim_cur > static_cast<rlim_t>(SQUID_MAXFD)) {

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.

I assume Squid supports exceeding SQUID_MAXFD -- existing Config.max_filedescriptors code above does not check SQUID_MAXFD.

I fear that this new check will break many existing legitimate descriptor increases via "inherited ulimit" because SQUID_MAXFD is going to be too small in those cases. There is nothing about "absurd" (using PR title terminology) in this proposed PR code. The proposed C++ comment says "unexpectedly large", but if overwriting SQUID_MAXFD via ulimit is supported, then we cannot claim that all reasonable ulimit values are "unexpected".

While working on the adjustments mentioned in another change request, I plan to add what this PR title promises -- detection of absurdly large inherited RLIMIT_NOFILE value.

Comment thread src/tools.cc
debugs(50, DBG_IMPORTANT, "WARNING: inherited RLIMIT_NOFILE (" <<
rl.rlim_cur << ") exceeds Squid's compiled descriptor limit (" <<
SQUID_MAXFD << "); limiting to " << SQUID_MAXFD);
rl.rlim_cur = SQUID_MAXFD;

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.

We should not overwrite rl, especially if we do not call setrlimit() with the new/overwritten value. We should set Squid_MaxFD directly instead.

While working on the adjustments mentioned in another change request, I will address this concern.

Comment thread src/tools.cc
return result;
}
#endif // _SQUID_WINDOWS_ || _SQUID_MINGW_

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.

Please restore the empty line at the end of the file.

I will fix this while working on the adjustments mentioned in another change request.

@rousskov rousskov added S-waiting-for-reviewer ready for review: Set this when requesting a (re)review using GitHub PR Reviewers box and removed S-waiting-for-author author action is expected (and usually required) labels Aug 26, 2026
@rousskov
rousskov self-requested a review August 26, 2026 15:18
@mxschmitt

Copy link
Copy Markdown
Author

Thanks @rousskov for taking over - highly appreciate your time you put into this project - really big fan of squid and using it in one of my side projects.

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

Labels

backport-to-v7 maintainer has approved these changes for v7 backporting S-waiting-for-reviewer ready for review: Set this when requesting a (re)review using GitHub PR Reviewers box

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants