Conversation
…into PPD
Route printer-make-and-model through a new ppd_escape_string() helper
before embedding into *Manufacturer, *ModelName, *Product, *NickName,
and *ShortNickName. This prevents an attacker-influenceable IPP
attribute (from an LAN mDNS-discovered printer picked up by
cups-browsed) that contains a raw newline, double-quote, or backslash
from breaking out of its quoted PPD string context and appearing as
additional PPD directives in the generated file.
This is a defense-in-depth fix. No downstream execution of injected
directives is demonstrated on the current cups-filters 1.28.17
(Debian bookworm) foomatic-rip parser, because its
first-declaration-wins semantics keep the injected directive dormant
behind the empty baseline template entry. The escape discipline
belongs in the emitter regardless: parser semantics are not a
contract the PPD generator can rely on across distros or future
refactors.
Add regression tests T08b-T08d in ppd/test_ppd_generator.c that
assert:
T08b \n in printer-make-and-model is squashed to a space; no
second '*directive' line appears in the output.
T08c " in printer-make-and-model is backslash-escaped.
T08d \ in printer-make-and-model is doubled.
The tests deliberately do NOT assert any specific downstream parser
behaviour; they lock in the emitter's escape discipline so future
refactors do not silently reopen the gap.
Context: reported as GHSA-5wv7-gqmh-2pf2 on the cups-filters
repository (routed here by upstream per zdohnal's feedback). No CVE
is requested; the disclosure is a defense-in-depth hardening PR
against the class of missing-blacklist-char bugs previously fixed
piecewise in filter/foomatic-rip/util.c
(CVE-2015-8327 backtick, CVE-2015-8560 semicolon).
Reporter: Pongsathon Sirithanyakul <pongsathon@itselectlab.com>
Co-credit: Warunyou Sunpachit, Khamolwan Hnunainam
(IT SELECT LAB Co., Ltd., Thailand)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Route
printer-make-and-modelthrough a newppd_escape_string()helper before embedding into the*Manufacturer,*ModelName,*Product,*NickName, and*ShortNickNamedirectives inppd/ppd-generator.c.Adds regression tests T08b / T08c / T08d in
ppd/test_ppd_generator.cthat assert newline, double-quote, and backslash inprinter-make-and-modelare neutralised before being written into the generated PPD.Why
printer-make-and-modelis a network-influenceable IPP string attribute: on an LAN withcups-browsedandavahi-daemonrunning (default on Debian task-desktop and most desktop installs), an mDNS-advertised printer's IPPGet-Printer-Attributesresponse feeds directly intoppdCreatePPDFromIPP2(), which today emits the value verbatim into a quoted PPD directive.A
\nin that value breaks out of the quoted string context and the following bytes are parsed as new PPD directives by the resulting file. I captured the intermediate PPD viaLD_PRELOADon Debian 12 bookworm (cups-filters 1.28.17-3+deb12u2) and confirmed that a payload of the formyields:
in the generated PPD.
What this PR is NOT claiming
I do not claim reachable RCE on shipping distros:
cups-filters 1.28.17+ Debian 12 combination I tested,foomatic-ripuses first-declaration-wins semantics and the baseline PPD template already emits*FoomaticRIPCommandLine:""(empty) before the make/model line. The injected directive is present in the PPD but is ignored by the downstream parser.The point of this PR is defense-in-depth: emitter escape discipline should not depend on any downstream parser happening to be lenient in a specific way. The class of bug is the same "incomplete blacklist" pattern that was previously fixed piecewise in
filter/foomatic-rip/util.c(CVE-2015-8327 backtick, CVE-2015-8560 semicolon).What the tests assert
The Group 2b tests deliberately only assert emitter behaviour (escape discipline in the resulting PPD text), not downstream parser behaviour:
\n→ single space; no\n*sequence appears in the output."→\"in the emitted value.\→\\in the emitted value.They do not assert any specific parser refuses execution, because that guarantee is a parser concern, not a generator concern.
Prior disclosure context
Originally filed as private GitHub Security Advisory
GHSA-5wv7-gqmh-2pf2againstOpenPrinting/cups-filterson 2026-09-22. Closed the same day by @zdohnal with routing feedback:Resubmitting the fix here — as a plain hardening PR without CVE framing — per that routing feedback. If the maintainers judge this warrants a CVE-ID, that decision is theirs to make; I am not requesting one.
Testing
gcc -fsyntax-onlyonppd/ppd-generator.cafter the change produces no new warnings/errors related to the new function or its call site. (Full build against libcupsfilters 2.x was not possible in my lab — the Debian 12 host only ships 1.x.)ci/autopkgtest(Debian) and cppcheck static-analysis workflows.ppd/test_ppd_generator.c(Group 2b, T08b–T08d), bringing the file's stated total to 48 assertions across 13 groups (was 45/12).Credit