Bug 2451739 (CVE-2026-4897)

Summary: CVE-2026-4897 polkit: Polkit: Denial of Service via unbounded input processing through standard input
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security DevOps Team <prodsec-dev>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedKeywords: Security
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in polkit. A local user can exploit this by providing a specially crafted, excessively long input to the `polkit-agent-helper-1` setuid binary via standard input (stdin). This unbounded input can lead to an out-of-memory (OOM) condition, resulting in a Denial of Service (DoS) for the system.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description OSIDB Bzimport 2026-03-26 14:27:24 UTC
The helper supports two ways to receive the cookie: via `argv[2]` when `argc == 3`, or via stdin when `argc == 2`. The latter is the path used by the polkit agent when it spawns the setuid helper: it passes only the username and writes the cookie on stdin (to avoid exposing it in process listings, as per CVE-2015-4625). The problematic code is in `src/polkitagent/polkitagenthelperprivate.c`:

```c
  if (argc == 3)
    return strdup (argv[2]);
  else
    {
      char *ret = NULL;
      size_t n = 0;
      ssize_t r = getline (&ret, &n, stdin);
      if (r == -1)
        {
          if (!feof (stdin))
            perror ("getline");
          free (ret);
          return NULL;
        }
      else
        {
          g_strchomp (ret);
          return ret;
        }
    }
```

There is no limit on the length of the line read from stdin. The helper checks that stdin is not a TTY when running as non-root (`isatty (STDIN_FILENO) != 0` → error), but it does not reject other sources such as pipes. Moreover, in all helper variants (PAM, shadow, bsdauth), the `isatty` check is performed **after** `read_cookie()` has already returned, so even if the check could somehow catch the attacker's input, the unbounded allocation would have already occurred. A local user can therefore run:

```sh
# No newline: getline() keeps reallocating until OOM or ENOMEM
python3 -c "print('A'*200000000, end='')" | /usr/lib/polkit-1/polkit-agent-helper-1 $(whoami)
```

The setuid binary is installed with mode 04755 (see `meson_post_install.py`), so any local user can execute it. This affects all helper variants (PAM, shadow, bsdauth) because they share `read_cookie()` in `polkitagenthelperprivate.c`. The stdin path was introduced in commit ea544ffc; releases from approximately 0.113 onward that use the setuid helper are affected. (Systems that use only the socket-activated helper and never run the setuid binary with user-controlled stdin are not exposed in practice.)