|
| 1 | +# Integrating Go- and Python-based OpenPrinting Projects in OSS-Fuzz |
| 2 | + |
| 3 | + |
| 4 | +* **Year**: 2025 |
| 5 | +* **Contributor**: Mohammed Imaduddin |
| 6 | +* **Organization**: OpenPrinting, The Linux Foundation |
| 7 | +* **Mentors**: Till Kamppeter, Jiongchi Yu, George Andrei Iosif |
| 8 | +* **Useful Links**: |
| 9 | + |
| 10 | + * [Project Page](https://summerofcode.withgoogle.com/programs/2025/projects/rBWHXaha) |
| 11 | + * [Source Code for Fuzz Harnesses](https://github.com/OpenPrinting/fuzzing) |
| 12 | + * [OSS-Fuzz](https://github.com/google/oss-fuzz) Projects |
| 13 | + |
| 14 | + * [goipp](https://github.com/google/oss-fuzz/tree/master/projects/goipp) |
| 15 | + * [ipp-usb](https://github.com/google/oss-fuzz/tree/master/projects/ipp-usb) |
| 16 | + * [pyppd](https://github.com/google/oss-fuzz/tree/master/projects/pyppd) |
| 17 | + * [pycups](https://github.com/google/oss-fuzz/tree/master/projects/pycups) |
| 18 | + * [IPP-over-USB Emulator](https://github.com/OpenPrinting/go-mfp/tree/master/proto/usbip) |
| 19 | + |
| 20 | + |
| 21 | +--- |
| 22 | + |
| 23 | +## Project Context and Significance |
| 24 | + |
| 25 | +OpenPrinting develops and maintains printing-related software, standards, and resources for Linux and other Unix-like systems. It maintains the printer/driver database and key components such as cups-filters and “Printer Applications” which enable IPP-based and driverless printing when used together with CUPS. While previous GSoC work successfully integrated C/C++-based OpenPrinting projects into OSS-Fuzz (achieving 21 bug fixes from 41 discovered issues), **no Go or Python projects had ever been integrated into OSS-Fuzz before this project**. |
| 26 | + |
| 27 | +This project addresses a significant gap in security testing for key printing infrastructure components: |
| 28 | + |
| 29 | +* **goipp** – A Go library maintained by OpenPrinting that implements the Internet Printing Protocol (IPP) for encoding and decoding IPP messages in Go. |
| 30 | + |
| 31 | +* **ipp-usb** – An OpenPrinting userspace daemon that exposes USB printers as local IPP network printers (IPP-over-USB proxy), enabling driverless printing for modern USB devices. |
| 32 | + |
| 33 | +* **pyppd** – A Python library/utility from OpenPrinting for reading, compressing, and decompressing PostScript Printer Description (PPD) files. |
| 34 | + |
| 35 | +* **pycups** – Python bindings to the CUPS API (libcups), allowing Python applications to manage printers and print jobs through CUPS. |
| 36 | + |
| 37 | +The challenge was particularly complex because these projects involve language bindings, hardware-dependent code, and network protocols that are difficult to test without specialized infrastructure. |
| 38 | + |
| 39 | +--- |
| 40 | + |
| 41 | +## Previous Work |
| 42 | + |
| 43 | +Building on the foundation established during GSoC 2024, the C/C++ integration work by Jiongchi Yu had already: |
| 44 | +- Integrated CUPS and libcups into OSS-Fuzz, discovering 41 security issues with 21 fixes |
| 45 | +- Established the [OpenPrinting/fuzzing](https://github.com/OpenPrinting/fuzzing) repository structure |
| 46 | +- Created workflows for maintaining fuzzing harnesses externally while integrating with OSS-Fuzz |
| 47 | +- Demonstrated the value of continuous fuzzing for critical printing infrastructure |
| 48 | + |
| 49 | +--- |
| 50 | + |
| 51 | +## Work Completed During This Project |
| 52 | + |
| 53 | +This project represents the **first successful integration of Go and Python projects into OSS-Fuzz**. |
| 54 | + |
| 55 | +### Technical Achievements by Project |
| 56 | + |
| 57 | +**goipp - Go IPP Implementation** |
| 58 | + |
| 59 | +* Created **5 comprehensive fuzz harnesses** targeting core IPP message processing: |
| 60 | + |
| 61 | + * `fuzz_decode_bytes.go`: Tests IPP message deserialization with malformed input |
| 62 | + * `fuzz_decode_bytes_ex.go`: Extended deserialization testing with additional parameters |
| 63 | + * `fuzz_collections.go`: Tests complex IPP Collection attribute handling |
| 64 | + * `fuzz_round_trip.go`: Validates encode/decode consistency to catch data corruption |
| 65 | + * `fuzz_tag_extension.go`: Tests custom IPP tag extensions parsing |
| 66 | +* **Pull Requests Created**: |
| 67 | + |
| 68 | + * [OpenPrinting/fuzzing PR #10](https://github.com/OpenPrinting/fuzzing/pull/10) |
| 69 | + * [OpenPrinting/fuzzing PR #11](https://github.com/OpenPrinting/fuzzing/pull/11) |
| 70 | + * [OpenPrinting/fuzzing PR #12](https://github.com/OpenPrinting/fuzzing/pull/12) |
| 71 | + * [OpenPrinting/fuzzing PR #13](https://github.com/OpenPrinting/fuzzing/pull/13) |
| 72 | + * [OpenPrinting/fuzzing PR #18](https://github.com/OpenPrinting/fuzzing/pull/18) |
| 73 | + * [OSS-Fuzz PRs for goipp](https://github.com/google/oss-fuzz/tree/master/projects/goipp) |
| 74 | + |
| 75 | +**ipp-usb - IPP-over-USB Daemon** |
| 76 | + |
| 77 | +* Developed **3 specialized fuzzers** for hardware-dependent code: |
| 78 | + |
| 79 | + * `daemon_fuzzer.go`: Tests the main daemon with malformed HTTP/IPP requests |
| 80 | + * `usb_fuzzer.go`: Tests USB protocol parsing using mock USB/IP infrastructure |
| 81 | + * `http_client_fuzzer.go`: Tests HTTP client resilience against malicious server responses |
| 82 | +* **Major Innovation**: Built a virtual IPP-over-USB emulator using USB/IP protocol, enabling fuzzing of hardware-dependent code paths without requiring physical USB printers |
| 83 | +* **Pull Requests Created**: |
| 84 | + |
| 85 | + * [OpenPrinting/fuzzing PR #26](https://github.com/OpenPrinting/fuzzing/pull/26) |
| 86 | + * [OSS-Fuzz PRs for ipp-usb](https://github.com/google/oss-fuzz/tree/master/projects/ipp-usb) |
| 87 | + |
| 88 | +**pyppd - Python PPD Archive Manager** |
| 89 | + |
| 90 | +* Implemented **7 Python fuzz harnesses** covering file processing and compression: |
| 91 | + |
| 92 | + * `fuzz_archive.py`: Tests PPD file archiving with malformed input |
| 93 | + * `fuzz_compress.py`: Tests compression/decompression of PPD files |
| 94 | + * `fuzz_compressor.py`: Tests round-trip compression consistency |
| 95 | + * `fuzz_find_files.py`: Tests file discovery with malicious patterns |
| 96 | + * `fuzz_ppd.py`: Tests PPD file parsing with corrupted data |
| 97 | + * `fuzz_read_file_in_syspath.py`: Tests system path file access |
| 98 | + * `fuzz_runner.py`: Tests command-line argument parsing |
| 99 | +* **Pull Requests Created**: |
| 100 | + |
| 101 | + * [OpenPrinting/fuzzing PR #31](https://github.com/OpenPrinting/fuzzing/pull/31) |
| 102 | + * [OpenPrinting/fuzzing PR #32](https://github.com/OpenPrinting/fuzzing/pull/32) |
| 103 | + * [OpenPrinting/fuzzing PR #36](https://github.com/OpenPrinting/fuzzing/pull/36) |
| 104 | + * [OpenPrinting/fuzzing PR #37](https://github.com/OpenPrinting/fuzzing/pull/37) |
| 105 | + * [OSS-Fuzz PRs for pyppd](https://github.com/google/oss-fuzz/tree/master/projects/pyppd) |
| 106 | + |
| 107 | +**pycups - Python CUPS Bindings** |
| 108 | + |
| 109 | +* Created **7 fuzz harnesses** for critical CUPS operations: |
| 110 | + |
| 111 | + * `fuzz_auth_callback.py`: Tests authentication callback handling |
| 112 | + * `fuzz_buffer_handling.py`: Tests buffer management and memory safety |
| 113 | + * `fuzz_file_handling.py`: Tests file I/O operations |
| 114 | + * `fuzz_ipp_io.py`: Tests IPP request/response processing |
| 115 | + * `fuzz_print_job.py`: Tests job submission with malformed parameters |
| 116 | + * `fuzz_printer_management.py`: Tests printer configuration operations |
| 117 | + * `fuzz_UTF8.py`: Tests string encoding/decoding across all functions |
| 118 | +* **Pull Requests Created**: |
| 119 | + |
| 120 | + * [OpenPrinting/fuzzing PR #27](https://github.com/OpenPrinting/fuzzing/pull/27) |
| 121 | + * [OpenPrinting/fuzzing PR #28](https://github.com/OpenPrinting/fuzzing/pull/28) |
| 122 | + * [OpenPrinting/fuzzing PR #29](https://github.com/OpenPrinting/fuzzing/pull/29) |
| 123 | + * [OpenPrinting/fuzzing PR #35](https://github.com/OpenPrinting/fuzzing/pull/35) |
| 124 | + * [OSS-Fuzz PRs for pycups](https://github.com/google/oss-fuzz/tree/master/projects/pycups) |
| 125 | + |
| 126 | +--- |
| 127 | + |
| 128 | +## Impact and Technical Challenges Overcome |
| 129 | + |
| 130 | +### Why This Work Was Difficult |
| 131 | + |
| 132 | +1. Integrated four very different OpenPrinting projects (Go libraries, Python bindings, and utilities) into OSS-Fuzz, each with its own language, build system and fuzzing engine. |
| 133 | +2. Dealt with hardware-dependent paths in ipp-usb and pycups by creating a virtual IPP-over-USB printer/emulator to fuzz code that normally requires real devices. |
| 134 | +3. Designed seed corpora and mutation strategies tailored to both IPP messages and legacy PPD files to exercise diverse input formats. |
| 135 | +4. Maintained all fuzzers externally and wired them into OSS-Fuzz with custom Dockerfiles and build scripts to keep upstream trees clean. |
| 136 | + |
| 137 | +### Quantified Impact |
| 138 | + |
| 139 | +- **Code Coverage Achieved**: [To be measured after September PRs get merged ;(] |
| 140 | +- **Projects Newly Covered**: 4 major OpenPrinting projects |
| 141 | + |
| 142 | +### Recommendations for Future Contributors |
| 143 | + |
| 144 | +1. Reuse and extend the existing fuzz harnesses and seed corpora instead of starting from scratch. |
| 145 | +2. Continue improving code coverage in hardware-dependent areas of ipp-usb by enhancing the virtual device emulator. |
| 146 | +3. Keep fuzzers in an external module and use clear build scripts/Dockerfiles to simplify OSS-Fuzz integration. |
| 147 | +4. Triage and upstream any OSS-Fuzz findings promptly to maintainers. |
| 148 | +5. Add unit tests alongside fuzzers to ensure deterministic coverage of critical functions. |
| 149 | + |
| 150 | +--- |
| 151 | + |
| 152 | +## Future Development |
| 153 | + |
| 154 | +1. Extend fuzzing coverage across all four projects by adding new harnesses and expanding the seed corpora to cover edge cases and rarely used code paths. |
| 155 | +2. Enhance the virtual IPP-over-USB emulator to simulate more device behaviors (if possible) for deeper fuzzing of hardware-dependent code. |
| 156 | +3. Integrate continuous fuzzing feedback by monitoring OSS-Fuzz reports and filing/triaging issues promptly with maintainers. |
| 157 | +4. Broaden test coverage in projects like pycups and pyppd by adding unit tests to complement fuzzing. |
| 158 | +5. Document the fuzzing setup so future contributors can easily reproduce, extend, and maintain it. |
| 159 | + |
| 160 | +--- |
| 161 | + |
| 162 | +## Acknowledgment |
| 163 | + |
| 164 | +I would like to thank my mentors for their guidance and support throughout this project. **Till Kamppeter** provided invaluable domain expertise on printing protocols and the OpenPrinting architecture. **George-Andrei Iosif** shared his deep knowledge of fuzzing methodologies and the **OSS-Fuzz** infrastructure. **Jiongchi Yu** deserves special recognition for his mentorship, building on his previous GSoC work and offering detailed technical guidance at every step, especially in fuzzing and OSS-Fuzz integration. I am also grateful to **Alexander Pevzner**, the author of **goipp** and **ipp-usb**, for helping me create fuzzing harnesses for these projects and for assisting in the development of the IPP-over-USB emulator using USB/IP. I would also like to thank **Google’s OSS-Fuzz maintainers** for promptly reviewing and merging pull requests. Finally, I thank the wider **OpenPrinting community** and the **Linux Foundation** for maintaining the projects and infrastructure that made this work possible. |
0 commit comments