Code: png_have_neon(png_structp png_ptr)
{
 FILE *f = fopen("/proc/cpuinfo", "rb");

 if (f != NULL)
 {
 /* This is a simple state machine which reads the input byte-by-byte until
       * it gets a match on the 'neon' feature or reaches the end of the stream.
       */
 static const char ch_feature[] = { 70, 69, 65, 84, 85, 82, 69, 83 };
 static const char ch_neon[] = { 78, 69, 79, 78 };

 enum
 {
 StartLine, Feature, Colon, StartTag, Neon, HaveNeon, SkipTag, SkipLine
 }  state;
 int counter;

 for (state=StartLine, counter=0;;)
 {
 int ch = fgetc(f);

 if (ch == EOF)
 {
 /* EOF means error or end-of-file, return false; neon at EOF is
             * assumed to be a mistake.
             */
            fclose(f);
 return 0;
 }

 switch (state)
 {
 case StartLine:
 /* Match spaces at the start of line */
 if (ch <= 32) /* skip control characters and space */
 break;

               counter=0;
               state = Feature;
 /* FALL THROUGH */

 case Feature:
 /* Match 'FEATURE', ASCII case insensitive. */
 if ((ch & ~0x20) == ch_feature[counter])
 {
 if (++counter == (sizeof ch_feature))

                      state = Colon;
                   break;
                }
                /* did not match 'feature' */
                state = SkipLine;
                /* FALL THROUGH */

 case SkipLine:
            skipLine:
 /* Skip everything until we see linefeed or carriage return */
 if (ch != 10 && ch != 13)
 break;

               state = StartLine;
 break;

 case Colon:
 /* Match any number of space or tab followed by ':' */
 if (ch == 32 || ch == 9)
 break;

 if (ch == 58) /* i.e. ':' */
 {
                  state = StartTag;
 break;
 }

 /* Either a bad line format or a 'feature' prefix followed by
                * other characters.
                */
               state = SkipLine;
 goto skipLine;

 case StartTag:
 /* Skip space characters before a tag */
 if (ch == 32 || ch == 9)
 break;

               state = Neon;
               counter = 0;
 /* FALL THROUGH */

 case Neon:
 /* Look for 'neon' tag */
 if ((ch & ~0x20) == ch_neon[counter])
 {
 if (++counter == (sizeof ch_neon))
                     state = HaveNeon;
 break;
 }

               state = SkipTag;
 /* FALL THROUGH */

 case SkipTag:
 /* Skip non-space characters */
 if (ch == 10 || ch == 13)
                  state = StartLine;

 else if (ch == 32 || ch == 9)
                  state = StartTag;
 break;

 case HaveNeon:
 /* Have seen a 'neon' prefix, but there must be a space or new
                * line character to terminate it.
                */
 if (ch == 10 || ch == 13 || ch == 32 || ch == 9)
 {
                  fclose(f);
 return 1;
 }

               state = SkipTag;
 break;

 default:
               png_error(png_ptr, "png_have_neon: internal error (bug)");
 }

       }
    }
 
    else
       png_warning(png_ptr, "/proc/cpuinfo open failed");
 
    return 0;
 }

Vulnerability Type: +Priv 
CWE ID: 
Summary: Unspecified vulnerability in libpng before 1.6.20, as used in Android 4.x before 4.4.4, 5.0.x before 5.0.2, 5.1.x before 5.1.1, and 6.x before 2016-07-01, allows attackers to gain privileges via a crafted application, as demonstrated by obtaining Signature or SignatureOrSystem access, aka internal bug 23265085.
Commit Message: DO NOT MERGE Update libpng to 1.6.20

BUG:23265085
Change-Id: I85199805636d771f3597b691b63bc0bf46084833
(cherry picked from commit bbe98b40cda082024b669fa508931042eed18f82)
