Bug 1308550 (CVE-2016-2191)

Summary: CVE-2016-2191 optipng: Invalid write while processing delta escapes without any boundary checking
Product: [Other] Security Response Reporter: Adam Mariš <amaris>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED WONTFIX QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: anemec, carnil, cbuissar, jgrulich, security-response-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-07-19 08:18:12 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1323936, 1323937    
Bug Blocks: 1308551    

Description Adam Mariš 2016-02-15 13:41:59 UTC
An out-of-bounds write vulnerability was reported that occurs when processing bitmap images due to crt_row being inc/dec-remented (depending on whether the image is topdown) while processing delta escapes without any boundary checking.

Vulnerable code (pngxrbmp.c):

| 210 static size_t
| 211 bmp_read_rows(png_bytepp begin_row, png_bytepp end_row, size_t row_size,
| 212 unsigned int compression, FILE *stream)
| 213 {
| ...
| 272 crt_row = begin_row;
| 273 for ( ; ; )
| 274 {
| 275 ch = getc(stream); b1 = (unsigned int)ch;
| 276 ch = getc(stream); b2 = (unsigned int)ch;
| 277 if (ch == EOF)
| 278 break;
| 279 if (b1 == 0) /* escape */
| 280 {
| ...
| 307 else if (b2 == 2) /* delta */
| 308 {
| 309 ch = getc(stream); b1 = (unsigned int)ch; /* horiz. offset */
| 310 ch = getc(stream); b2 = (unsigned int)ch; /* vert. offset */
| ...
| 314 if (b2 > (size_t)((end_row - crt_row) * inc))
| 315 b2 = (unsigned int)((end_row - crt_row) * inc);
| 316 for ( ; b2 > 0; --b2)
| 317 {
| ...
| 319 crt_row += inc;
| ...
| 322 }
| ...
| 324 }
| 325 else /* b2 >= 3 bytes in absolute mode */
| 326 {
| 327 len = (b2 <= endn - crtn) ? b2 : (unsigned int)(endn - crtn);
| 328 if (bmp_fread_fn(*crt_row, crtn, len, stream) != len)
| 329 break;
| 330 crtn += len;
| 331 }
| 332 }
| ...
| 352 }

A delta escape moving crt_row beyond its allocated chunk followed by fread() in absolute mode would, with GNU libc combined with a !topdown image, result in a write to an address based on the specified bitmap height.

Upstream report : https://sourceforge.net/p/optipng/bugs/59/
Patch is merged with CVE-2016-3981, presented as a set of 2 patches :
  -> https://sourceforge.net/p/optipng/bugs/56/#5168
  -> https://sourceforge.net/p/optipng/bugs/56/#d6e6

Comment 3 Andrej Nemec 2016-04-05 06:32:41 UTC
Created optipng tracking bugs for this issue:

Affects: fedora-all [bug 1323936]
Affects: epel-all [bug 1323937]

Comment 4 Andrej Nemec 2016-04-05 06:33:31 UTC
Public via:

http://seclists.org/oss-sec/2016/q2/10

Comment 7 Fedora Update System 2016-06-18 19:01:33 UTC
optipng-0.7.6-1.fc24 has been pushed to the Fedora 24 stable repository. If problems still persist, please make note of it in this bug report.

Comment 8 Fedora Update System 2016-06-25 23:23:30 UTC
optipng-0.7.6-1.fc23 has been pushed to the Fedora 23 stable repository. If problems still persist, please make note of it in this bug report.

Comment 9 Cedric Buissart 2016-07-19 08:16:02 UTC
Statement:

Red Hat Product Security has rated this issue as having Moderate security impact. This issue is not currently planned to be addressed in future updates. For additional information, refer to the Issue Severity Classification: https://access.redhat.com/security/updates/classification/.