Bugzilla will be upgraded to version 5.0 on a still to be determined date in the near future. The original upgrade date has been delayed.
Bug 624438 - (CVE-2010-2941) CVE-2010-2941 cups: cupsd memory corruption vulnerability
CVE-2010-2941 cups: cupsd memory corruption vulnerability
Status: CLOSED ERRATA
Product: Security Response
Classification: Other
Component: vulnerability (Show other bugs)
unspecified
All Linux
high Severity high
: ---
: ---
Assigned To: Red Hat Product Security
impact=important,source=customer,repo...
: Security
Depends On: 646767 646768 646769 646770 652161
Blocks:
  Show dependency treegraph
 
Reported: 2010-08-16 09:21 EDT by Tomas Hoger
Modified: 2018-10-15 07:21 EDT (History)
5 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2011-01-07 07:46:48 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
cups-value-tag-mismatch.patch (2.13 KB, patch)
2010-08-16 10:21 EDT, Tim Waugh
no flags Details | Diff
cups-CVE-2010-2941-EL5.patch (1.84 KB, patch)
2010-08-31 11:36 EDT, Tim Waugh
no flags Details | Diff
Alternate fix from Mike Sweet, upstream CUPS author and maintainer (2.27 KB, patch)
2010-08-31 15:44 EDT, Tomas Hoger
no flags Details | Diff
Mike's patch back-ported to RHEL5 (1.88 KB, patch)
2010-09-01 06:06 EDT, Tim Waugh
no flags Details | Diff


External Trackers
Tracker ID Priority Status Summary Last Updated
CUPS Bugs and Features 3648 None None None Never
Red Hat Product Errata RHSA-2010:0811 normal SHIPPED_LIVE Important: cups security update 2010-10-28 21:44:07 EDT
Red Hat Product Errata RHSA-2010:0866 normal SHIPPED_LIVE Important: cups security update 2010-11-09 14:00:34 EST

  None (edit)
Description Tomas Hoger 2010-08-16 09:21:56 EDT
Emmanuel Bouillon reported a memory corruption flaw in CUPS daemon.  A specially-crafted IPP request can cause daemon to crash or, possibly, execute arbitrary code.

Acknowledgements:

Red Hat would like to thank Emmanuel Bouillon of NATO C3 Agency for reporting this issue.
Comment 1 Tim Waugh 2010-08-16 10:20:11 EDT
The problem is a mismatch between different memory allocators.

In the IPP protocol, an attribute can have multiple values, and each value is typed.  In the CUPS data model for this, all values for a given attribute must have the same (or a compatible) type.

String types have values allocated with the StrAlloc allocator, a reference-counting string pool.

'Unknown' types use malloc.

By giving the first value for an attribute a value tag of 56, which does not correspond to any particular value type and so is 'unknown', but which also is accepted as 'compatible' with string types due to the value tag range check, CUPS does not reject the request.  The 'unknown' value is allocated using malloc; the remaining values are allocated using StrAlloc.

When the in-memory request is freed, free() is used for all values including those allocated using StrAlloc.

The solution is to use exactly the same conditions when deciding how to allocate the value as when freeing it.

The initial value is allocated using malloc(), as it does not match any of the value tag cases.  Successive values are allocated using StrAlloc because they are string types.

Here is the compatibility check just before the successive values are allocated (cups/ipp.c); here, value_tag is the value tag given to the first value, and tag is the value tag given to the current (successive) value:

           /*
            * Make sure we aren't adding a new value of a different
            * type...
            */

            if (value_tag == IPP_TAG_ZERO)
            {
             /*
              * Setting the value of a collection member...
              */

              attr->value_tag = tag;
            }
            else if ((value_tag >= IPP_TAG_TEXTLANG &&
                      value_tag <= IPP_TAG_MIMETYPE))
            {
             /*
              * String values can sometimes come across in different
              * forms; accept sets of differing values...
              */
             /*
              * String values can sometimes come across in different
              * forms; accept sets of differing values...
              */

              if ((tag < IPP_TAG_TEXTLANG || tag > IPP_TAG_MIMETYPE) &&
                  tag != IPP_TAG_NOVALUE)
              {
                DEBUG_printf(("1ippReadIO: 1setOf value tag %x(%s) != %x(%s)",
                              value_tag, ippTagString(value_tag), tag,
                              ippTagString(tag)));
                ipp_buffer_release(buffer);
                return (IPP_ERROR);
              }
            }
            else if (value_tag != tag)
            {
              DEBUG_printf(("1ippReadIO: value tag %x(%s) != %x(%s)",
                            value_tag, ippTagString(value_tag), tag,
                            ippTagString(tag)));
              ipp_buffer_release(buffer);
              return (IPP_ERROR);
            }

Now, IPP_TAG_TEXTLANG < 56 < IPP_TAG_MIMETYPE, so '56' is allowed to be compatible with string types -- even though it uses a different allocator.

Here is how the data is freed:

    default :
        if (!((int)attr->value_tag & IPP_TAG_COPY))
        {
          for (i = 0, value = attr->values;
               i < attr->num_values;
               i ++, value ++)
            if (value->unknown.data)
              free(value->unknown.data);
        }
        break;

(because all the values are collected together under the '56' value tag).

As far as I have been able to tell from source code inspection, all versions of CUPS are vulnerable to this denial of service attack.
Comment 2 Tim Waugh 2010-08-16 10:21:18 EDT
Created attachment 438968 [details]
cups-value-tag-mismatch.patch

Patch attached (for RHEL-6) to fix the compatibility check to use exactly the same checking as in _ippAttrFree().
Comment 3 Tim Waugh 2010-08-16 11:43:30 EDT
RHEL-3 and RHEL-4 are not vulnerable to this because they do not use the string pool/StrAlloc allocator, only malloc (in fact strdup).
Comment 5 Tomas Hoger 2010-08-17 05:33:51 EDT
(In reply to comment #1)
> As far as I have been able to tell from source code inspection, all versions
> of CUPS are vulnerable to this denial of service attack.

There are differences in the impact between 1.3 and 1.4 CUPS versions due to the differences in the way _cups_sp_item_t is organized.

In 1.4, _cups_sp_item_t is:

     71 typedef struct _cups_sp_item_s		/**** String Pool Item ****/
     72 {
     73 #  ifdef DEBUG_GUARDS
     74   unsigned int	guard;			/* Guard word */
     75 #  endif /* DEBUG_GUARDS */
     76   unsigned int	ref_count;		/* Reference count */
     77   char		str[1];			/* String */
     78 } _cups_sp_item_t;

_cupsStrAlloc() allocates new item as:
  calloc(1, sizeof(_cups_sp_item_t) + strlen(s))

and returns str pointer.  Therefore, _cupsStrFree() calls free() on a value point to the middle of the malloced chunk, triggering glibc malloc checks failure and abort.

In 1.3, _cups_sp_item_t is:

     69 typedef struct _cups_sp_item_s		/**** String Pool Item ****/
     70 {
     71   char		*str;			/* String */
     72   unsigned int	ref_count;		/* Reference count */
     73 } _cups_sp_item_t;

and str is strdup()-allocated independently of the structure.  Hence value passed to free() from _cupsStrFree() points to valid malloc()ed chunk that can be freed, but string pool item is not properly ref-counted and removed from string pool, that may lead to use-after-free with possible additional memory corruptions.
Comment 8 Tomas Hoger 2010-08-25 09:08:14 EDT
Status update: we still don't have any embargo date proposal from Apple security team.  No changes in the upstream bug.
Comment 9 Tim Waugh 2010-08-31 11:36:03 EDT
Created attachment 442221 [details]
cups-CVE-2010-2941-EL5.patch

Same patch back-ported to Red Hat Enterprise Linux 5.
Comment 10 Tomas Hoger 2010-08-31 15:44:52 EDT
Created attachment 442263 [details]
Alternate fix from Mike Sweet, upstream CUPS author and maintainer
Comment 11 Tim Waugh 2010-09-01 06:06:33 EDT
Created attachment 442372 [details]
Mike's patch back-ported to RHEL5
Comment 12 Tomas Hoger 2010-09-03 04:45:17 EDT
Update from Apple Product Security:

We're currently planning on including this fix in our next Mac OS X update.  At this time, we don't have a date for when the fix might be available.
Comment 13 manu 2010-09-23 10:19:31 EDT
6 weeks now. Any news regarding the disclosure date?
Comment 14 Tomas Hoger 2010-09-23 10:34:30 EDT
No update from Apple on disclosure date so far.
Comment 15 Tomas Hoger 2010-10-05 03:43:02 EDT
New upstream release is expected in about 1 month, based on what we've been told.
Comment 18 Tomas Hoger 2010-10-26 03:41:27 EDT
Apple is planning to release late this week.
Comment 20 Vincent Danen 2010-10-28 21:29:18 EDT
The new upstream release is not available yet, but we have been given the go-ahead to observe the original embargo (today) and release.
Comment 22 errata-xmlrpc 2010-10-28 21:44:12 EDT
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5

Via RHSA-2010:0811 https://rhn.redhat.com/errata/RHSA-2010-0811.html
Comment 23 errata-xmlrpc 2010-11-10 13:57:55 EST
This issue has been addressed in following products:

  Red Hat Enterprise Linux 6

Via RHSA-2010:0866 https://rhn.redhat.com/errata/RHSA-2010-0866.html
Comment 24 Tomas Hoger 2010-11-11 03:15:21 EST
Created cups tracking bugs for this issue

Affects: fedora-all [bug 652161]

Note You need to log in before you can comment on or make changes to this bug.