[cups-devel] Solution to lpadmin crashing when discovering HP printers

Stephan stephanwib at googlemail.com
Thu Oct 6 04:08:52 PDT 2016


Hi!

Replying to my previous mail: I have set up a SLES 12 box with which I
was able to work on the cups binaries with gdb. The issue is that the
printer reports the following properites:

<key>media-col-default</key>
<dict>
<key>media-size</key>
<dict>
<key>x-dimension</key>
<integer>0</integer>
<key>y-dimension</key>
<integer>0</integer>
</dict>


This leads to a problem in the following code path in cups/ppd-cache.c:

--------------------------------------------------------------
  if ((defattr = ippFindAttribute(response, "media-col-default",
IPP_TAG_BEGIN_COLLECTION)) != NULL)
  {
    if ((attr = ippFindAttribute(ippGetCollection(defattr, 0),
"media-size", IPP_TAG_BEGIN_COLLECTION)) != NULL)
    {
      media_size = ippGetCollection(attr, 0);
      x_dim      = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
      y_dim      = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);

      if (x_dim && y_dim)
      {
        pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
        strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
      }
      else
        strlcpy(ppdname, "Unknown", sizeof(ppdname));
    }
-----------------------------------------------------------------------

The values of the dimensions are not checked and pwgMediaForSize()
returns a NULL pointer which is then accessed.

-------------------------------------------------------------------
(gdb) b pwgMediaForSize
Function "pwgMediaForSize" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (pwgMediaForSize) pending.
(gdb) r
Starting program: /opt/cups-2.2.1/sbin/lpadmin -p hp-e -v
ipp://10.70.235.32/ -m everywhere
Missing separate debuginfos, use: zypper install
glibc-debuginfo-2.19-31.9.x86_64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1, pwgMediaForSize (width=0, length=0) at pwg-media.c:911
911       return (_pwgMediaNearSize(width, length, 176));
(gdb) bt
#0  pwgMediaForSize (width=0, length=0) at pwg-media.c:911
#1  0x00007ffff7b96522 in _ppdCreateFromIPP (buffer=0x7fffffffa2f0
"/tmp/01cbc57fd2a31", bufsize=16384, response=0x55555576af60) at
ppd-cache.c:3151
#2  0x000055555555887c in get_printer_ppd (uri=0x55555575f0a4
"ipp://10.70.235.32/", buffer=0x7fffffffa2f0 "/tmp/01cbc57fd2a31",
bufsize=16384) at lpadmin.c:1204
#3  0x0000555555557345 in main (argc=7, argv=0x7fffffffe3f8) at lpadmin.c:596
(gdb) finish
Run till exit from #0  pwgMediaForSize (width=0, length=0) at pwg-media.c:911
0x00007ffff7b96522 in _ppdCreateFromIPP (buffer=0x7fffffffa2f0
"/tmp/01cbc57fd2a31", bufsize=16384, response=0x55555576af60) at
ppd-cache.c:3151
3151            pwg = pwgMediaForSize(ippGetInteger(x_dim, 0),
ippGetInteger(y_dim, 0));
Value returned is $1 = (pwg_media_t *) 0x0
(gdb) quit
------------------------------------------------------------------

Please see below for a possible solution:

-------------------------------------------------------------------
--- cups/ppd-cache.c.org    2016-10-06 14:10:34.087111069 +0200
+++ cups/ppd-cache.c    2016-10-06 14:51:35.731054469 +0200
@@ -3149,10 +3149,11 @@
       if (x_dim && y_dim)
       {
         pwg = pwgMediaForSize(ippGetInteger(x_dim, 0),
ippGetInteger(y_dim, 0));
-    strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
+    if (pwg)
+      strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
+        else
+          strlcpy(ppdname, "Unknown", sizeof(ppdname));
       }
-      else
-    strlcpy(ppdname, "Unknown", sizeof(ppdname));
     }
     else
       strlcpy(ppdname, "Unknown", sizeof(ppdname));
------------------------------------------------------------------


Regards,

Stephan



More information about the cups mailing list