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.)