← Back to team overview

desktop-packages team mailing list archive

[Bug 1519914] Re: CUPS filter crashes on memory allocation when run by CUPS but works when run manually

 

The relevant code behind the cupsArrayNew() function in the CUPS library
(libcups, cups/array.[ch] in the cups source package) is the following:

----------
struct _cups_array_s			/**** CUPS array structure ****/
{
  int			num_elements,	/* Number of array elements */
			alloc_elements,	/* Allocated array elements */
			current,	/* Current element */
			insert,		/* Last inserted element */
			unique,		/* Are all elements unique? */
			num_saved,	/* Number of saved elements */
			saved[_CUPS_MAXSAVE];
					/* Saved elements */
  void			**elements;	/* Array elements */
  cups_array_func_t	compare;	/* Element comparison function */
  void			*data;		/* User data passed to compare */
  cups_ahash_func_t	hashfunc;	/* Hash function */
  int			hashsize,	/* Size of hash */
			*hash;		/* Hash array */
  cups_acopy_func_t	copyfunc;	/* Copy function */
  cups_afree_func_t	freefunc;	/* Free function */
};

typedef struct _cups_array_s cups_array_t; /* This line is in
cups/array.h, all the rest in cups/array.c */

cups_array_t *				/* O - Array */
cupsArrayNew(cups_array_func_t f,	/* I - Comparison function or @code NULL@ for an unsorted array */
             void              *d)	/* I - User data pointer or @code NULL@ */
{
  return (cupsArrayNew3(f, d, 0, 0, 0, 0));
}

cups_array_t *				/* O - Array */
cupsArrayNew3(cups_array_func_t  f,	/* I - Comparison function or @code NULL@ for an unsorted array */
              void               *d,	/* I - User data or @code NULL@ */
              cups_ahash_func_t  h,	/* I - Hash function or @code NULL@ for unhashed lookups */
	      int                hsize,	/* I - Hash size (>= 0) */
	      cups_acopy_func_t  cf,	/* I - Copy function */
	      cups_afree_func_t  ff)	/* I - Free function */
{
  cups_array_t	*a;			/* Array  */


 /*
  * Allocate memory for the array...
  */

  a = calloc(1, sizeof(cups_array_t));
  if (!a)
    return (NULL);

[...]

  return (a);
}
----------

We have cups_array_t, a data structure of around 20 elements of ordinary
types (~100 - 200 bytes), and cupsArrayNew() calls cupsArrayNew3() which
allocates memory for this data structure with the calloc() function. The
code not shown does nothing else than filling in the elements of the
structure.

So the crash is caused by the calloc() call trying to allocate 100 - 200
bytes of memory.

-- 
You received this bug notification because you are a member of Desktop
Packages, which is subscribed to cups-filters in Ubuntu.
https://bugs.launchpad.net/bugs/1519914

Title:
  CUPS filter crashes on memory allocation when run by CUPS but works
  when run manually

Status in Canonical System Image:
  Confirmed
Status in cups-filters package in Ubuntu:
  Confirmed

Bug description:
  I have started to test the printing stack of Ubuntu on the phone (see
  also bug 1509423, same setup as in that bug).

  I have a Nexus 4 now to test the printing stack on the phone.

  First I have updated the USB-connected phone to the development branch
  of the OS via

  ubuntu-device-flash touch --channel=devel

  with the phone booted into Ubuntu and the screen unlocked.

  After the reboot of the phone I have run

  phablet-config writable-image

  to be able to install packages with apt-get and entered a shell on the
  phone via

  phablet-shell

  In the shell I first installed a level-1 printing stack (See
  https://blueprints.launchpad.net/ubuntu/+spec/client-1305-printing-
  stack-with-mobile-in-mind for the levels):

  sudo apt-get install cups-daemon cups-browsed avahi-daemon

  This makes the following new packages getting installed:

  The following NEW packages will be installed:
    avahi-daemon bc bind9-host cups-browsed cups-daemon libavahi-core7
    libavahi-glib1 libbind9-90 libcupsmime1 libdaemon0 libdns100 libgeoip1
    libisc95 libisccc90 libisccfg90 liblwres90 libpaper1 ssl-cert
  0 upgraded, 18 newly installed, 0 to remove and 0 not upgraded.
  Need to get 1,502 kB of archives.
  After this operation, 4,698 kB of additional disk space will be used.

  The installation was hanging on the postinst of CUPS, so I had to open
  a new shell in another terminal and kill the postinst for the
  installation process to finish.

  sudo apt-get install -f

  has re-run the CUPS postinst and this time it finished.

  As the phone apps do not yet have a print dialog I needed a print
  client on the phone, and also some tools for developing and debugging.
  So I have installed cups-client, giving me command line printing and
  print admin commands, as lp, lpstat, lpinfo, lpadmin, ...:

  sudo apt-get install cups-client
  [...]
  The following NEW packages will be installed:
    cups-client cups-common libcupsfilters1 libcupsimage2
  0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
  Need to get 368 kB of archives.
  After this operation, 2,810 kB of additional disk space will be used.

  PID 1 on the phone is still Upstart, Upstart is configured to start
  CUPS on-demand, via

  /etc/init/cups.override

  cups.override needs to be corrected, as cupsd does not support the
  "-x" option any more, so I have removed the "-x 30" from the cupsd
  command line. Now cupsd starts when running commands like

  lpstat -r
  lpstat -v
  ...

  After that I did

  sudo start cups-browsed

  to start cups-browsed to get the queues from remote CUPS servers
  locally available (level 1 printing stack).

  lpstat -v

  shows my printers shared on remote CUPS servers now.

  Note that CUPS admin tasks need "sudo" as the "phablet" user is not in
  the "lpadmin" group.

  For the printing tests I do the CUPS logging (in
  /var/log/cups/error_log) in debug mode, running

  sudo cupsctl --debug-logging

  sudo cupsctl

  shows my settings.

  Now I print via

  lp -d printer ~/.bashrc

  and this works (after the fix of bug 1509423 and after making cups-
  browsed use URIs with IP addresses, using cups-filters 1.1.0 and
  setting "IPBasedDeviceURIs On" in /etc/cups/cups-browsed.conf).

  with printer being a CUPS queue set up on my laptop and shared there.
  It is made available on the phone by cups-browsed. Printing on this
  kind of print queues works, so the level-1 printing stack works.

  Now I have advanced to the level-2 printing stack, meaning that I also
  want to directly (without an additional computer) support native
  network printers (IPP printers which understand PostScript, PDF, PCL,
  PWG-Raster, IPP Everywhere) with generic drivers and without need of a
  printer setup tool.

  For that I installed the packages needed for the level-2 printing
  stack:

  sudo apt-get install cups-core-drivers cups-filters-core-drivers

  and I have created two directories which are missing (another bug,
  fixed already in the Debian GIT repository of the CUPS package):

  sudo mkdir /etc/cups/ppd
  sudo mkdir /etc/cups/interfaces

  Now everything is installed for cups-browsed to be able to create
  print queues for said native IPP printers. To actually get cups-
  browsed creating such queues we set "CreateIPPPrinterQueues Yes" in
  /etc/cups/cups-browsed.conf and restart cups-browsed.

  I have an HP DeskJet Ink Advantage 2540 with WiFi in my network and it
  is discovered as PCL printer.

  cups-browsed fails to gain enough data from the printer to auto-create
  a PPD file, and so it creates a queue based on a System V interface
  script (in /etc/cups/interfaces) using the universal print filter
  /usr/lib/cups/filter/sys5ippprinter which calls the needed chain of
  CUPS filters.

  When printing a job

  lp -d HP-Deskjet-2540-series ~/Kaiser-Natron\ ABC_DIN_A4.pdf

  the printout fails with a crash of sys5ippprinter, getting the
  following in /var/log/cups/error_log:

  ----------
  ...
  D [25/Nov/2015:15:38:04 -0200] [Job 40] Filter gstoraster or Ghostscript (/usr/b
  in/gs) missing for "output-format=application/vnd.hp-PCL,image/jpeg,application/
  PCLm,image/urf", using pdftoraster.
  D [25/Nov/2015:15:38:04 -0200] [Job 40] Printer supports output formats: applica
  tion/vnd.hp-PCL,image/jpeg,application/PCLm,image/urf
  D [25/Nov/2015:15:38:04 -0200] [Job 40] Using following CUPS filter chain to con
  vert input data to the PCL 5c/e format: gziptoany pdftopdf pdftoraster rastertop
  clx
  D [25/Nov/2015:15:38:04 -0200] [Job 40] argv[0]="/usr/lib/cups/filter/sys5ipppri
  nter"
  D [25/Nov/2015:15:38:04 -0200] [Job 40] argv[1]="40"
  D [25/Nov/2015:15:38:04 -0200] [Job 40] argv[2]="phablet"
  D [25/Nov/2015:15:38:04 -0200] [Job 40] argv[3]="Kaiser-Natron ABC_DIN_A4.pdf"
  D [25/Nov/2015:15:38:04 -0200] [Job 40] argv[4]="1"
  D [25/Nov/2015:15:38:04 -0200] [Job 40] argv[5]="cups-browsed finishings=3 make-and-model=HP-Deskjet-2540-series media=iso_a4_210x297mm media-bottom-margin=1438 media-left-margin=318 media-right-margin=318 media-top-margin=152 number-up=1 output-format=application/vnd.hp-PCL,image/jpeg,application/PCLm,image/urf job-uuid=urn:uuid:cf68b655-2efb-3840-7206-3a12e6ed40cf job-originating-host-name=localhost time-at-creation=1448473084 time-at-processing=1448473084 media-class= print-color-mode=RGB"
  D [25/Nov/2015:15:38:04 -0200] [Job 40] argv[6]="/tmp/01bf1565d0f8d"
  D [25/Nov/2015:15:38:04 -0200] [Job 40] sys5ippprinter: malloc.c:2373: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.
  D [25/Nov/2015:15:38:05 -0200] [Job 40] Aborted (core dumped)
  D [25/Nov/2015:15:38:05 -0200] [Job 40] PID 7151 (/etc/cups/interfaces/HP-Deskjet-2540-series) stopped with status 134 (Numerical result out of range)
  D [25/Nov/2015:15:38:05 -0200] [Job 40] PID 7152 (/usr/lib/cups/backend/ipp) exited with no errors.
  D [25/Nov/2015:15:38:05 -0200] cupsdMarkDirty(----S)
  D [25/Nov/2015:15:38:05 -0200] cupsdSetBusyState: newbusy="Printing jobs and dirty files", busy="Dirty files"
  E [25/Nov/2015:15:38:05 -0200] [Job 40] Job stopped due to filter errors; please consult the error_log file for details.
  ...
  ----------

  The crash seems to be a problem with memory allocation when the
  sys5ippprinter filter tries to create a CUPS array for managing the
  PIDs of the called subprocesses:

  ----------
  /*
   * 'exec_filters()' - Execute filters for the given file and options.
   */

  static int				/* O - 0 on success, 1 on error */
  exec_filters(cups_array_t  *filters,	/* I - Array of filters to run */
  	     char	   **argv)	/* I - Filter options */
  {
    int		i;			/* Looping var */
    char		program[1024];		/* Program to run */
    char		*filter,		/* Current filter */
  		*next;			/* Next filter */
    int		current,		/* Current filter */
  		filterfds[2][2],	/* Pipes for filters */
  		pid,			/* Process ID of filter */
  		status,			/* Exit status */
  		retval;			/* Return value */
    cups_array_t	*pids;			/* Executed filters array */
    filter_pid_t	*pid_entry,		/* Entry in executed filters array */
  		key;			/* Search key for filters */
    const char	*cups_serverbin;	/* CUPS_SERVERBIN environment variable */

   /*
    * Remove NULL ("-") filters...
    */

    for (filter = (char *)cupsArrayFirst(filters);
         filter;
         filter = (char *)cupsArrayNext(filters))
      if (!strcmp(filter, "-"))
        cupsArrayRemove(filters, filter);

    for (i = 0; argv[i]; i ++)
      fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);

   /*
    * Execute all of the filters...
    */

    pids            = cupsArrayNew((cups_array_func_t)compare_pids, NULL);
  ...
  ----------

  The crash happens in the "pids = cupsArrayNew(...);" line.

  The crash does not happen when one calls the filter manually:

  ./sys5ippprinter 1 1 1 1 "cups-browsed finishings=3 make-and-model=HP-
  Deskjet-2540-series media=iso_a4_210x297mm media-bottom-margin=1438
  media-left-margin=318 media-right-margin=318 media-top-margin=152
  number-up=1 output-format=application/vnd.hp-
  PCL,image/jpeg,application/PCLm,image/urf job-uuid=urn:uuid:0b368837
  -113a-37e5-6aa5-8c7c910acfcb job-originating-host-name=localhost time-
  at-creation=1447114787 time-at-processing=1447114787 media-class=
  print-color-mode=RGB" ~/Kaiser-Natron\ ABC_DIN_A4.pdf > out.pcl

  I have also looked for any AppArmor ("audit")  messages in
  /var/log/syslog and there are none. The problem persists after:

  sudo aa-complain /usr/sbin/cupsd
  sudo aa-complain /usr/sbin/cups-browsed

  So it is perhaps a problem of not enough memory available when running
  from CUPS. Can it be that CUPS is running in some restricted memory?

To manage notifications about this bug go to:
https://bugs.launchpad.net/canonical-devices-system-image/+bug/1519914/+subscriptions