Version in base suite: 3.22.10+dfsg0-8.1 Base version: hplip_3.22.10+dfsg0-8.1 Target version: hplip_3.22.10+dfsg0-8.1+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/h/hplip/hplip_3.22.10+dfsg0-8.1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/h/hplip/hplip_3.22.10+dfsg0-8.1+deb13u1.dsc changelog | 15 + patches/CVE-2026-8631_8632.patch | 578 +++++++++++++++++++++++++++++++++++++++ patches/series | 2 3 files changed, 595 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpm1erx9z6/hplip_3.22.10+dfsg0-8.1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpm1erx9z6/hplip_3.22.10+dfsg0-8.1+deb13u1.dsc: no acceptable signature found diff -Nru hplip-3.22.10+dfsg0/debian/changelog hplip-3.22.10+dfsg0/debian/changelog --- hplip-3.22.10+dfsg0/debian/changelog 2025-04-13 13:10:47.000000000 +0000 +++ hplip-3.22.10+dfsg0/debian/changelog 2026-07-25 15:39:02.000000000 +0000 @@ -1,3 +1,18 @@ +hplip (3.22.10+dfsg0-8.1+deb13u1) trixie-security; urgency=high + + * CVE-2026-8631 (Closes: #1137374) + a potential security vulnerability might allow escalation of + privileges and/or arbitrary code execution when handling crafted + print data. + * CVE-2026-8632 + a potential security vulnerability might allow escalation of + privileges and/or arbitrary code execution via operating system + command injection. + * with the help of Marc Deslauriers from Ubuntu, patches are extracted + from hplip 3.26.4 + + -- Thorsten Alteholz Sat, 25 Jul 2026 17:39:02 +0200 + hplip (3.22.10+dfsg0-8.1) unstable; urgency=medium * Non-maintainer upload. diff -Nru hplip-3.22.10+dfsg0/debian/patches/CVE-2026-8631_8632.patch hplip-3.22.10+dfsg0/debian/patches/CVE-2026-8631_8632.patch --- hplip-3.22.10+dfsg0/debian/patches/CVE-2026-8631_8632.patch 1970-01-01 00:00:00.000000000 +0000 +++ hplip-3.22.10+dfsg0/debian/patches/CVE-2026-8631_8632.patch 2026-07-24 17:14:36.000000000 +0000 @@ -0,0 +1,578 @@ +Description: fix multiple security issues +Origin: extracted from hplip 3.26.4 + +Index: hplip-3.22.10+dfsg0/base/device.py +=================================================================== +--- hplip-3.22.10+dfsg0.orig/base/device.py 2026-07-24 19:14:31.172354970 +0200 ++++ hplip-3.22.10+dfsg0/base/device.py 2026-07-24 19:14:31.168354933 +0200 +@@ -508,6 +508,8 @@ + raise ERROR_INTERNAL + + for ip in detected_devices: ++ if not ip: ++ continue + update_spinner() + hn = detected_devices[ip].get('hn', '?UNKNOWN?') + num_devices_on_jd = detected_devices[ip].get('num_devices', 0) +Index: hplip-3.22.10+dfsg0/base/utils.py +=================================================================== +--- hplip-3.22.10+dfsg0.orig/base/utils.py 2026-07-24 19:14:31.172354970 +0200 ++++ hplip-3.22.10+dfsg0/base/utils.py 2026-07-24 19:14:31.168354933 +0200 +@@ -474,7 +474,7 @@ + + + def commafy(val): +- return locale.format("%s", val, grouping=True) ++ return locale.format_string("%s", val, grouping=True) + + + def format_bytes(s, show_bytes=False): +@@ -2331,11 +2331,10 @@ + log.debug("Not found") + return (0, '') + +-# checks if given process is running. +-#return value: +-# True or False +-# None - if process is not running +-# grep output - if process is running ++# Check whether any running process command line contains the requested name. ++# Return value: ++# (True, {pid: cmdline, ...}) when one or more matching processes are found ++# (False, {}) when no matching process is found or enumeration fails + + def Is_Process_Running(process_name): + if not process_name: +@@ -2343,28 +2342,27 @@ + + try: + process = {} +- p1 = Popen(["ps", "-w", "-w", "aux"], stdout=PIPE) +- p2 = Popen(["grep", process_name], stdin=p1.stdout, stdout=PIPE) +- p3 = Popen(["grep", "-v", "grep"], stdin=p2.stdout, stdout=PIPE) +- output = p3.communicate()[0] +- log.debug("Is_Process_Running output = %s " %output) +- +- if output: +- for p in output.splitlines(): +- cmd = "echo '%s' | awk {'print $2'}" %p +- status,pid = subprocess.getstatusoutput(cmd) +- cmd = "echo '%s' | awk {'print $11,$12'}" %p +- status,cmdline = subprocess.getstatusoutput(cmd) +- if pid : ++ for entry in os.listdir('/proc'): ++ if not entry.isdigit(): ++ continue ++ pid = entry ++ try: ++ with open('/proc/%s/cmdline' % pid, 'rb') as f: ++ raw = f.read() ++ cmdline = raw.replace(b'\x00', b' ').decode('utf-8', 'replace').strip() ++ if process_name in cmdline: + process[pid] = cmdline ++ except (IOError, OSError): ++ continue + ++ log.debug("Is_Process_Running matches = %s " % process) ++ if process: + return True, process + else: + return False, {} + + except Exception as e: +- log.error("Execution failed: process Name[%s]" %process_name) +- print >>sys.stderr, "Execution failed:", e ++ log.error("Execution failed: process Name[%s] - error - %s" % (process_name, str(e))) + return False, {} + + +Index: hplip-3.22.10+dfsg0/common/utils.h +=================================================================== +--- hplip-3.22.10+dfsg0.orig/common/utils.h 2026-07-24 19:14:31.172354970 +0200 ++++ hplip-3.22.10+dfsg0/common/utils.h 2026-07-24 19:14:31.168354933 +0200 +@@ -4,6 +4,10 @@ + #include + #include + #include ++#include ++#include ++#include ++#include + //#include "hpmud.h" + + #define _STRINGIZE(x) #x +@@ -54,6 +58,52 @@ + }; + + ++/* Safe multiplication helpers - prevent integer overflow */ ++ ++/** ++ * safe_mul_size_t - Safely multiply two size_t values ++ * @a: First operand ++ * @b: Second operand ++ * @out: Output buffer for result ++ * Returns: true if multiplication succeeded, false if overflow detected ++ */ ++static inline bool safe_mul_size_t(size_t a, size_t b, size_t *out) ++{ ++ if (!out) ++ return false; ++ if (a == 0 || b == 0) ++ { ++ *out = 0; ++ return true; ++ } ++ if (a > ((size_t)-1) / b) ++ return false; ++ *out = a * b; ++ return true; ++} ++ ++/** ++ * safe_mul_int_positive - Safely multiply two positive integers ++ * @a: First operand (must be >= 0) ++ * @b: Second operand (must be >= 0) ++ * @out: Output buffer for result ++ * Returns: true if multiplication succeeded, false if negative input or overflow detected ++ */ ++static inline bool safe_mul_int_positive(int a, int b, int *out) ++{ ++ if (!out || a < 0 || b < 0) ++ return false; ++ if (a == 0 || b == 0) ++ { ++ *out = 0; ++ return true; ++ } ++ if (a > INT_MAX / b) ++ return false; ++ *out = a * b; ++ return true; ++} ++ + #ifdef __cplusplus + extern "C" { + #endif +Index: hplip-3.22.10+dfsg0/prnt/hpcups/genPCLm.cpp +=================================================================== +--- hplip-3.22.10+dfsg0.orig/prnt/hpcups/genPCLm.cpp 2026-07-24 19:14:31.172354970 +0200 ++++ hplip-3.22.10+dfsg0/prnt/hpcups/genPCLm.cpp 2026-07-24 19:14:31.168354933 +0200 +@@ -127,6 +127,7 @@ + #include + #include + #include ++#include + #include + //#include + +@@ -1674,7 +1675,12 @@ + destColorSpace=PCLmPageContent->dstColorSpaceSpefication; + + // Calculate how large the output buffer needs to be based upon the page specifications +- int tmp_outBuffSize=mediaWidthInPixels*currStripHeight*dstNumComponents; ++ int tmp_outBuffSize=0; ++ if(!safe_mul_int_positive(mediaWidthInPixels,currStripHeight,&tmp_outBuffSize) || ++ !safe_mul_int_positive(tmp_outBuffSize,dstNumComponents,&tmp_outBuffSize)) ++ { ++ return(errorOutAndCleanUp()); ++ } + + if(tmp_outBuffSize>currOutBuffSize) + { +@@ -1742,7 +1748,14 @@ + { + // We need to pad the scratchBuffer size to allow for compression expansion (RLE can create + // compressed segments that are slightly larger than the source. +- scratchBuffer=(ubyte*)malloc(currStripHeight*mediaWidthInPixels*srcNumComponents*2); ++ size_t scratchSize=0; ++ if(currStripHeight<=0 || mediaWidthInPixels<=0 || srcNumComponents<=0 || ++ !safe_mul_size_t((size_t)currStripHeight, (size_t)mediaWidthInPixels, &scratchSize) || ++ !safe_mul_size_t(scratchSize, (size_t)srcNumComponents, &scratchSize) || ++ !safe_mul_size_t(scratchSize, 2u, &scratchSize)) ++ return(errorOutAndCleanUp()); ++ ++ scratchBuffer=(ubyte*)malloc(scratchSize); + if(!scratchBuffer) + return(errorOutAndCleanUp()); + /*if(DebugIt2) +@@ -1798,7 +1811,9 @@ + int PCLmGenerator::Encapsulate(void *pInBuffer, int inBufferSize, int thisHeight, void **pOutBuffer, int *iOutBufferSize) + { + int result=0, numCompBytes; +- int scanlineWidth=mediaWidthInPixels*srcNumComponents; ++ int scanlineWidth=0; ++ if(!safe_mul_int_positive(mediaWidthInPixels, srcNumComponents, &scanlineWidth)) ++ return(errorOutAndCleanUp()); + int compSize; + // int numLinesThisCall=inBufferSize/(currSourceWidth*srcNumComponents); + int numLinesThisCall=thisHeight; +@@ -1888,7 +1903,8 @@ + { + colorConvertSource(sourceColorSpace, grayScale, (ubyte*)localInBuffer, currSourceWidth, numLinesThisCall); + // Adjust the scanline width accordingly +- scanlineWidth = mediaWidthInPixels * dstNumComponents; ++ if(!safe_mul_int_positive(mediaWidthInPixels, dstNumComponents, &scanlineWidth)) ++ return(errorOutAndCleanUp()); + } + + if(leftMarginInPix) +@@ -1903,7 +1919,11 @@ + } + + #ifdef SUPPORT_WHITE_STRIPS +- bool whiteStrip=isWhiteStrip(pInBuffer, thisHeight*currSourceWidth*srcNumComponents); ++ int whiteStripLen=0; ++ if(!safe_mul_int_positive(thisHeight, currSourceWidth, &whiteStripLen) || ++ !safe_mul_int_positive(whiteStripLen, srcNumComponents, &whiteStripLen)) ++ return(errorOutAndCleanUp()); ++ bool whiteStrip=isWhiteStrip(pInBuffer, whiteStripLen); + if(DebugIt2) + { + if(whiteStrip){ +@@ -1922,9 +1942,14 @@ + if(firstStrip && topMarginInPix) + { + ubyte whitePt=0xff; +- +- ubyte *tmpStrip=(ubyte*)malloc(scanlineWidth*topMarginInPix); +- memset(tmpStrip,whitePt,scanlineWidth*topMarginInPix); ++ size_t tmpStripSize=0; ++ if(!safe_mul_size_t((size_t)scanlineWidth, (size_t)topMarginInPix, &tmpStripSize)) ++ return(errorOutAndCleanUp()); ++ ++ ubyte *tmpStrip=(ubyte*)malloc(tmpStripSize); ++ if(!tmpStrip) ++ return(errorOutAndCleanUp()); ++ memset(tmpStrip,whitePt,tmpStripSize); + + + for(sint32 stripCntr=0; stripCntruser_name); + if(DebugIt2) + { +- dbglog("Allocated zlib dest buffer of size %d\n",numLinesThisCall*scanlineWidth); ++ dbglog("Allocated zlib dest buffer of size %d\n",sourceLen); + dbglog("zlib compression return result=%d, compSize=%d\n",result,(int)destSize); + } + free(newStripPtr); +@@ -2030,12 +2063,12 @@ + } + else + { +- result=compress((Bytef*)scratchBuffer, &destSize, (const Bytef*)localInBuffer, scanlineWidth*numLinesThisCall); ++ result=compress((Bytef*)scratchBuffer, &destSize, (const Bytef*)localInBuffer, (uLong)sourceLen); + if(DebugIt2) + writeOutputFile(destSize, scratchBuffer, m_pPCLmSSettings->user_name); + if(DebugIt2) + { +- dbglog("Allocated zlib dest buffer of size %d\n",numLinesThisCall*scanlineWidth); ++ dbglog("Allocated zlib dest buffer of size %d\n",sourceLen); + dbglog("zlib compression return result=%d, compSize=%d\n",result,(int)destSize); + } + } +@@ -2044,14 +2077,23 @@ + + else if(currCompressionDisposition==compressRLE) + { ++ int sourceLen=0; ++ if(!safe_mul_int_positive(numLinesThisCall, scanlineWidth, &sourceLen)) ++ return(errorOutAndCleanUp()); ++ + if(firstStrip && topMarginInPix) + { + ubyte whitePt=0xff; ++ size_t tmpStripSize=0; ++ if(!safe_mul_size_t((size_t)scanlineWidth, (size_t)topMarginInPix, &tmpStripSize)) ++ return(errorOutAndCleanUp()); + + // We need to inject a blank image-strip with a height==topMarginInPix + +- ubyte *tmpStrip=(ubyte*)malloc(scanlineWidth*topMarginInPix); +- memset(tmpStrip,whitePt,scanlineWidth*topMarginInPix); ++ ubyte *tmpStrip=(ubyte*)malloc(tmpStripSize); ++ if(!tmpStrip) ++ return(errorOutAndCleanUp()); ++ memset(tmpStrip,whitePt,tmpStripSize); + + for(sint32 stripCntr=0; stripCntrStartJob((void**)&m_pOutBuffer, &m_OutBuffSize); +- err = sendBuffer(static_cast(m_pOutBuffer), m_OutBuffSize); +- m_pHbpl1Wrapper->FreeBuffer(m_pOutBuffer, m_OutBuffSize); ++ if (err != NO_ERROR) ++ { ++ return err; ++ } ++ if (m_pOutBuffer != NULL && m_OutBuffSize > 0) ++ { ++ err = sendBuffer(static_cast(m_pOutBuffer), m_OutBuffSize); ++ m_pHbpl1Wrapper->FreeBuffer(m_pOutBuffer, m_OutBuffSize); ++ if (err != NO_ERROR) ++ { ++ return err; ++ } ++ } + + if (m_PrintinGrayscale == ON){ //Grayscale = ON + m_ColorMode = COLORTYPE_BOTH; +@@ -156,8 +167,15 @@ + } + + err = m_pHbpl1Wrapper->EndJob((void**)&m_pOutBuffer, &m_OutBuffSize); +- err = sendBuffer(static_cast(m_pOutBuffer), m_OutBuffSize); +- m_pHbpl1Wrapper->FreeBuffer(m_pOutBuffer, m_OutBuffSize); ++ if (err != NO_ERROR) ++ { ++ return err; ++ } ++ if (m_pOutBuffer != NULL && m_OutBuffSize > 0) ++ { ++ err = sendBuffer(static_cast(m_pOutBuffer), m_OutBuffSize); ++ m_pHbpl1Wrapper->FreeBuffer(m_pOutBuffer, m_OutBuffSize); ++ } + return err; + } + +@@ -167,8 +185,15 @@ + DRIVER_ERROR err = NO_ERROR; + + err = m_pHbpl1Wrapper->StartPage((void**)&m_pOutBuffer, &m_OutBuffSize); +- err = sendBuffer(static_cast(m_pOutBuffer), m_OutBuffSize); +- m_pHbpl1Wrapper->FreeBuffer(m_pOutBuffer, m_OutBuffSize); ++ if (err != NO_ERROR) ++ { ++ return err; ++ } ++ if (m_pOutBuffer != NULL && m_OutBuffSize > 0) ++ { ++ err = sendBuffer(static_cast(m_pOutBuffer), m_OutBuffSize); ++ m_pHbpl1Wrapper->FreeBuffer(m_pOutBuffer, m_OutBuffSize); ++ } + return err; + } + +@@ -188,29 +213,51 @@ + ************************************************************************************/ + DRIVER_ERROR Hbpl1::FormFeed () + { ++ DRIVER_ERROR err = NO_ERROR; + + if (0 != m_numScanLines && m_pbyStripData && 0 != m_nStripSize) + { + ++m_nBandCount; +- m_pHbpl1Wrapper->Encapsulate(m_pbyStripData, m_nStripSize, m_nStripHeight, (void**)&m_pOutBuffer, &m_OutBuffSize); +- sendBuffer(m_pOutBuffer, m_OutBuffSize); ++ err = m_pHbpl1Wrapper->Encapsulate(m_pbyStripData, m_nStripSize, m_nStripHeight, (void**)&m_pOutBuffer, &m_OutBuffSize); ++ if (err != NO_ERROR) ++ return err; ++ if (m_pOutBuffer != NULL && m_OutBuffSize > 0) ++ { ++ err = sendBuffer(m_pOutBuffer, m_OutBuffSize); ++ if (err != NO_ERROR) ++ return err; ++ } + memset(m_pbyStripData,0xFF,m_nStripSize); + } + + while(m_nBandCount < m_numStrips) + { + ++m_nBandCount; +- m_pHbpl1Wrapper->Encapsulate(m_pbyStripData, m_nStripSize, m_nStripHeight, (void**)&m_pOutBuffer, &m_OutBuffSize); +- sendBuffer(m_pOutBuffer, m_OutBuffSize); ++ err = m_pHbpl1Wrapper->Encapsulate(m_pbyStripData, m_nStripSize, m_nStripHeight, (void**)&m_pOutBuffer, &m_OutBuffSize); ++ if (err != NO_ERROR) ++ return err; ++ if (m_pOutBuffer != NULL && m_OutBuffSize > 0) ++ { ++ err = sendBuffer(m_pOutBuffer, m_OutBuffSize); ++ if (err != NO_ERROR) ++ return err; ++ } + } + +- m_pHbpl1Wrapper->EndPage((void**)&m_pOutBuffer, &m_OutBuffSize); +- sendBuffer(m_pOutBuffer, m_OutBuffSize); ++ err = m_pHbpl1Wrapper->EndPage((void**)&m_pOutBuffer, &m_OutBuffSize); ++ if (err != NO_ERROR) ++ return err; ++ if (m_pOutBuffer != NULL && m_OutBuffSize > 0) ++ { ++ err = sendBuffer(m_pOutBuffer, m_OutBuffSize); ++ if (err != NO_ERROR) ++ return err; ++ } + m_pHbpl1Wrapper->FreeBuffer(m_pOutBuffer,m_OutBuffSize); + m_nBandCount = 0; + m_numScanLines = 0; + +- return NO_ERROR; ++ return err; + + } + +Index: hplip-3.22.10+dfsg0/prnt/hpcups/Hbpl1_Wrapper.cpp +=================================================================== +--- hplip-3.22.10+dfsg0.orig/prnt/hpcups/Hbpl1_Wrapper.cpp 2026-07-24 19:14:31.172354970 +0200 ++++ hplip-3.22.10+dfsg0/prnt/hpcups/Hbpl1_Wrapper.cpp 2026-07-24 19:14:31.168354933 +0200 +@@ -77,19 +77,31 @@ + + DRIVER_ERROR Hbpl1Wrapper::StartJob(void **pOutBuffer, int *pOutBufferSize) + { +- DRIVER_ERROR err = NO_ERROR; +- +- m_pPCLmGenerator->StartJob(pOutBuffer,pOutBufferSize,false); +- return err; ++ int ret = m_pPCLmGenerator->StartJob(pOutBuffer,pOutBufferSize,false); ++ if (ret != success) ++ { ++ if (pOutBuffer) ++ *pOutBuffer = NULL; ++ if (pOutBufferSize) ++ *pOutBufferSize = 0; ++ return SYSTEM_ERROR; ++ } ++ return NO_ERROR; + } + + + DRIVER_ERROR Hbpl1Wrapper::EndJob(void **pOutBuffer, int *pOutBufferSize) + { +- DRIVER_ERROR err = NO_ERROR; +- +- m_pPCLmGenerator->EndJob(pOutBuffer,pOutBufferSize); +- return err; ++ int ret = m_pPCLmGenerator->EndJob(pOutBuffer,pOutBufferSize); ++ if (ret != success) ++ { ++ if (pOutBuffer) ++ *pOutBuffer = NULL; ++ if (pOutBufferSize) ++ *pOutBufferSize = 0; ++ return SYSTEM_ERROR; ++ } ++ return NO_ERROR; + } + + +@@ -173,8 +185,15 @@ + + PCLmPageContent.duplexDisposition = (duplexDispositionEnum)o_Hbpl1->m_JA.args_duplex_mode; + +- m_pPCLmGenerator->StartPage(&PCLmSContent,true,pOutBuffer,pOutBufferSize); +- ++ int ret = m_pPCLmGenerator->StartPage(&PCLmSContent,true,pOutBuffer,pOutBufferSize); ++ if (ret != success) ++ { ++ if (pOutBuffer) ++ *pOutBuffer = NULL; ++ if (pOutBufferSize) ++ *pOutBufferSize = 0; ++ return SYSTEM_ERROR; ++ } + + return err; + } +@@ -182,9 +201,16 @@ + + DRIVER_ERROR Hbpl1Wrapper::EndPage(void **pOutBuffer, int *pOutBufferSize) + { +- DRIVER_ERROR err = NO_ERROR; +- m_pPCLmGenerator->EndPage(pOutBuffer, pOutBufferSize); +- return err; ++ int ret = m_pPCLmGenerator->EndPage(pOutBuffer, pOutBufferSize); ++ if (ret != success) ++ { ++ if (pOutBuffer) ++ *pOutBuffer = NULL; ++ if (pOutBufferSize) ++ *pOutBufferSize = 0; ++ return SYSTEM_ERROR; ++ } ++ return NO_ERROR; + } + + +@@ -195,9 +221,16 @@ + + DRIVER_ERROR Hbpl1Wrapper::Encapsulate (void *pInBuffer, int inBufferSize, int numLines, void **pOutBuffer, int *pOutBufferSize) + { +- DRIVER_ERROR err = NO_ERROR; +- m_pPCLmGenerator->Encapsulate(pInBuffer, inBufferSize, numLines, pOutBuffer, pOutBufferSize); +- return err; ++ int ret = m_pPCLmGenerator->Encapsulate(pInBuffer, inBufferSize, numLines, pOutBuffer, pOutBufferSize); ++ if (ret != success) ++ { ++ if (pOutBuffer) ++ *pOutBuffer = NULL; ++ if (pOutBufferSize) ++ *pOutBufferSize = 0; ++ return SYSTEM_ERROR; ++ } ++ return NO_ERROR; + } + + DRIVER_ERROR Hbpl1Wrapper::SkipLines (int iSkipLines) diff -Nru hplip-3.22.10+dfsg0/debian/patches/series hplip-3.22.10+dfsg0/debian/patches/series --- hplip-3.22.10+dfsg0/debian/patches/series 2025-04-13 13:10:47.000000000 +0000 +++ hplip-3.22.10+dfsg0/debian/patches/series 2026-07-24 17:07:51.000000000 +0000 @@ -87,3 +87,5 @@ 0087-Use-read_file-instead-of-readfp-for-python-3.12.patch 0088-remove-hash-symbol-from-ppd-files.patch 0089-Makefile.am-Install-D-Bus-policy-in-usr-not-etc.patch + +CVE-2026-8631_8632.patch