bug : cupsd crashes / misbehaves on malformed Authorization: Negotiate header (unchecked malloc + decode in GSSAPI path)
Maintainer thường phản hồi trong vòng 1 ngày
@michaelrsweet đang làm issue này rồi.
Từ ngày 18/10/2026.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 70/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- c
- Lĩnh vực
- authentication, backend, security
Hướng nghiên cứu
Đọc phần xử lý Negotiate trong scheduler/auth.c:847-851 và hành vi của bộ giải mã trong cups/http-support.c:463-464, :509. Biên dịch cupsd với HAVE_GSSAPI và AuthType Negotiate, sau đó thử token Authorization sai định dạng được mô tả trong issue. Công việc hoàn tất khi đầu vào không hợp lệ bị từ chối trước khi đến gss_accept_sec_context, không làm daemon bị treo hoặc hoạt động sai.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Before you write the report
I read REPORTING_ISSUES.md before filing this. This is a code defect in the daemon's auth path, so no printer was needed — I verified the logic locally with a small repro mirroring the exact calls.
I searched open + closed issues and PRs for GSSAPI, Negotiate, gss_accept_sec_context, httpDecode64_2, Kerberos to avoid a duplicate. The closest I found were #1609 (OAuth/OIDC token-validation gaps) and #1766 (ipp backend musl stack crash) — both are different subsystems and neither touches this Negotiate decode path. So I believe this is fresh.
Describe the bug
Hey, while looking at the Kerberos / Negotiate handling in scheduler/auth.c I noticed the input token setup does not check for failures at all.
On current master (b37c10e8, v2.5b1), scheduler/auth.c:847-851:
len = (int)strlen(authorization) + 0;
input_token.value = malloc((size_t)len);
input_token.value = httpDecode64_2(input_token.value, &len,
authorization);
input_token.length = (size_t)len;
Two problems stacked on top of each other:
malloc()at:848is never NULL-checked.authorizationhere is the remainder of the client-sentAuthorization: Negotiate ...header, so a remote client controls its length.httpDecode64_2()at:849can returnNULL(seecups/http-support.c:463-464— it returnsNULLwhen!outlen || *outlen < 1, andhttpDecode64_3underneath returnsNULLon bad input at:509). ThatNULLis assigned straight back overinput_token.valuewith no check.
Right after that, the token goes directly into:
major_status = gss_accept_sec_context(&minor_status,
&context,
ServerCreds,
&input_token, // <- possibly NULL .value here
...);
So a malformed (or huge, OOM-inducing) Negotiate header can push a NULL / garbage token buffer into gss_accept_sec_context() inside cupsd itself, which runs as root and pre-auth. At best the daemon logs a confusing GSS error, at worst it trips over the bad buffer in the GSS library.
What made me look twice is that the Basic path just above (:600-602) decodes into a fixed stack buffer username[] safely, while this path uses a heap allocation with no checks. Felt like an oversight worth flagging.
To Reproduce
I could not spin up a Kerberos KDC here, so I extracted the exact 3-line sequence into a tiny repro that mirrors the real httpDecode64_2 NULL contract:
char *v = malloc((size_t)len); // mirrors :848, no check
v = fake_httpDecode64_2(v, &len, "!!!not-base64!!!");
// mirrors :849, returns NULL on bad input
printf("after decode: value=%p len=%d\n", (void*)v, len);
Steps:
- Save as
repro_gss.cand build:
cc -O0 repro_gss.c -o repro_gss && ./repro_gss
- You will see:
after decode: value=0x0 len=16
REPRODUCED: input_token.value==NULL fed to gss_accept_sec_context -> root cupsd robustness bug
Matches scheduler/auth.c:847-851: malloc unchecked + httpDecode64_2 NULL unchecked
- Full daemon path: send
Authorization: Negotiate !!!not-base64!!!(or a very long token to pressuremalloc) to acupsdbuilt withHAVE_GSSAPIandAuthType Negotiate— theNULLtoken reachesgss_accept_sec_context()instead of being rejected cleanly.
Honestly the malloc-OOM half needs memory pressure to trigger, but the malformed-base64 NULL half triggers on demand — that is the part I actually reproduced above.
Expected behavior
Reject the bad token cleanly before touching GSS, something like:
len = (int)strlen(authorization);
input_token.value = malloc((size_t)len);
if (!input_token.value)
return;
if (!httpDecode64_2(input_token.value, &len, authorization))
{
free(input_token.value);
return;
}
input_token.length = (size_t)len;
Even better long term would be moving this to httpDecode64_3 like the rest of the tree, since httpDecode64_2 is already marked deprecated. But the NULL checks alone fix the crash path with no behavior change.
Screenshots
N/A — daemon auth path, repro output pasted above.
System Information:
- OS and its version: macOS arm64 (clang 17) for the logic repro — affects any Linux cupsd built with GSSAPI/Kerberos
- Application:
cupsd(scheduler/auth.c),AuthType Negotiate - CUPS version: master 2.5b1 @
b37c10e8
Additional context
A couple of notes from my digging:
- Impact is daemon robustness — pre-auth remote header reaches root
cupsd. Not claiming RCE, just a genuine NULL-into-GSS path that should be a clean reject. - I checked the sibling decode sites:
:404and:602use stack buffers with size init, only this:848-849site uses unchecked heap allocation. So this looks like a one-off miss, not a pattern.
- Ngôn ngữ chính
- C
- Star
- 1.8k
- Fork
- 354
- Merge trung bình
- 20 giờ 6 phút
- Pull request đã merge (30 ngày)
- 18
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của OpenPrinting/cups
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
OpenPrinting/cups#1795 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Don't use xgettext sort option (-s) when generating POT fileCó thể đã có người làm @michaelrsweet đã nhận 19 ngày trước. Đang mởinvestigating
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
OpenPrinting/cups#1721 · 4 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 1-2 ngày Mức phù hợp với người mới 15/100
OpenPrinting/cups#1804 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 20/100
OpenPrinting/cups#1802 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
OpenPrinting/cups#1796 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của OpenPrinting/cups
Issue tương tự
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 83/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
containers/bubblewrap#826 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Vulkan: create_device reads the device extension list after freeing it (random crash at start)Đang mở
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 62/100
Revivedx/SavageWindRecomp#488 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
needs-device
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
-
feature/themes QA/No release-notes/exclude tests tests/missing-coverage tests/test-quality
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
brave/brave-browser#60971 ·
Maintainer thường phản hồi trong vòng 1 ngày