RubySec

Providing security resources for the Ruby community

GHSA-rf6g-xhmp-gm7v (puma): Accept loop retries without pausing when out of file descriptors, flooding the log

Accept loop retries without pausing when out of file descriptors, flooding the log

Published: November 13, 2026

SECURITY IDENTIFIERS

GEM

puma

PATCHED VERSIONS

~> 7.2.2 >= 8.0.3

DESCRIPTION

Impact

An unauthenticated client can make Puma:

  1. write log lines as fast as it can…
  2. …which eventually may fill the disk…
  3. …and when the disk fills, Puma will stop accepting connections.

The client can do this by opening enough idle connections to use up the process's file descriptors.

When accept fails because the process is out of file descriptors (EMFILE), the connection stays in the listen backlog, so the listening socket stays readable. Puma logs the error and calls accept again at once, with no pause. Each attempt fails the same way and writes another "Listen loop" error line. An attacker who opens about as many idle connections as the file descriptor limit, and sends nothing on them, keeps Puma in this loop. The attacker reconnects when Puma closes idle connections after first_data_timeout, so the loop does not end.

If the log destination then raises an error, such as ENOSPC when the disk is full, that error escapes the listen loop and ends the thread that accepts connections.

Deployments that accept connections directly from clients are affected, including the default configuration.

Deployments behind a reverse proxy or load balancer that limits connections to Puma are not affected, because the client cannot open enough connections to Puma itself.

Acknowledgements

Found by Puma's maintainers during an internal security review.

RELATED