Project: flex (westes/flex), language: c++
Vulnerability instance: flex.cve-2019-6293
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/westes/flex/issues/414
## Description:
Issue: westes/flex#414
Title: Stack Comsumption Problem Caused By the mark_beginning_as_normal Function Making Recursive Calls to Itself
State: open
Created by: wcventure
Created at: 2019-01-09 07:06:10+00:00

Issue Body:
Hi there,

An issue was discovered in function mark_beginning_as_normal in nfa.c, as distributed in flex 2.6.4. There is a stack exhaustion problem caused by the in mark_beginning_as_normal function making recursive calls to itself in certain scenarios involving lots of '*' characters.

Here is the POC file. Please use the “./flex $POC” to reproduce the bug.
[POC.zip](https://github.com/westes/flex/files/2739794/POC.zip)

Command：“./flex $POC”


The ASAN dumps the stack trace as follows:

```
AddressSanitizer:DEADLYSIGNAL
=================================================================
==30349==ERROR: AddressSanitizer: stack-overflow on address 0x7fffacc27ff8 (pc 0x00000056c257 bp 0x7fffacc28000 sp 0x7fffacc27f80 T0)
    #0 0x56c256 in mark_beginning_as_normal /flex/src/nfa.c:337
    #1 0x56c5e7 in mark_beginning_as_normal /flex/src/nfa.c:348:5
    #2 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #3 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #4 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #5 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #6 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #7 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #8 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #9 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #10 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #11 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #12 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #13 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #14 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #15 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #16 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #17 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #18 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #19 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #20 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #21 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #22 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #23 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #24 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #25 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #26 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #27 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #28 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #29 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #30 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #31 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #32 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #33 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #34 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #35 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #36 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #37 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #38 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #39 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #40 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #41 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #42 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #43 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #44 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #45 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #46 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #47 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #48 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #49 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #50 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #51 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #52 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #53 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #54 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #55 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #56 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #57 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #58 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #59 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #60 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #61 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #62 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #63 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #64 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #65 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #66 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #67 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #68 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #69 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #70 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #71 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #72 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #73 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #74 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #75 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #76 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #77 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #78 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #79 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #80 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #81 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #82 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #83 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #84 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #85 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #86 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #87 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #88 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #89 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #90 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #91 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #92 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #93 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #94 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #95 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #96 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #97 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #98 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #99 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #100 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #101 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #102 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #103 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #104 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #105 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #106 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #107 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #108 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #109 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #110 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #111 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #112 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #113 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #114 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #115 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #116 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #117 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #118 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #119 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #120 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #121 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #122 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #123 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #124 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #125 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #126 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #127 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #128 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #129 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #130 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #131 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #132 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #133 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #134 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #135 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #136 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #137 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #138 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #139 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #140 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #141 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #142 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #143 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #144 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #145 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #146 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #147 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #148 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #149 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #150 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #151 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #152 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #153 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #154 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #155 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #156 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #157 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #158 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #159 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #160 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #161 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #162 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #163 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #164 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #165 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #166 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #167 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #168 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #169 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #170 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #171 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #172 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #173 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #174 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #175 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #176 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #177 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #178 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #179 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #180 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #181 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #182 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #183 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #184 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #185 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #186 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #187 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #188 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #189 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #190 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #191 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #192 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #193 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #194 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #195 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #196 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #197 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #198 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #199 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #200 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #201 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #202 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #203 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #204 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #205 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #206 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #207 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #208 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #209 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #210 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #211 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #212 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #213 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #214 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #215 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #216 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #217 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #218 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #219 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #220 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #221 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #222 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #223 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #224 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #225 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #226 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #227 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #228 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #229 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #230 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #231 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #232 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #233 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #234 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #235 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #236 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #237 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #238 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #239 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #240 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #241 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #242 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #243 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #244 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #245 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #246 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #247 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #248 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5
    #249 0x56c74f in mark_beginning_as_normal /flex/src/nfa.c:351:5

SUMMARY: AddressSanitizer: stack-overflow /flex/src/nfa.c:337 in mark_beginning_as_normal
==30349==ABORTING
```


Comments:
Comment by wcventure on 2019-01-09 07:06:37+00:00:
We can directly look at the snippet code of nfa.c to see if it is possible to have infinite recursion. Intuitively, in some cases, function mark_beginning_as_normal shows the behavior of recursive calls.

```
void    mark_beginning_as_normal (int mach) {
	switch (state_type[mach]) {
	case STATE_NORMAL:
		/* Oh, we've already visited here. */
		return;

	case STATE_TRAILING_CONTEXT:
		state_type[mach] = STATE_NORMAL;

		if (transchar[mach] == SYM_EPSILON) {
			if (trans1[mach] != NO_TRANSITION)
				mark_beginning_as_normal (trans1[mach]);

			if (trans2[mach] != NO_TRANSITION)
				mark_beginning_as_normal (trans2[mach]);
		}
		break;
	
	}
}
```

This is simply running out of stack space. You can make the number of recursions go up by 11,000 or so by dynamically allocating variables instead of using stack space, but at the end of the day, you can work around this (for this test case) by doing:

`ulimit -s 4096`

Of course, a much larger (deeper) YAML file will still make it crash. You can thus, make it happen far faster by doing:

`ulimit -s 256`

The crash does not seem to happen due to any buffer overflows or memory corruption; it's simply the kernel saying "you're out of stack space, please die". One simple way to avoid the crash itself is to do a depth-check of the tree and compare it to some value related to the stack size returned and produce an error if the values are way out of whack.

A more complicated solution would involve removing recursion, which looks like it would not be a trivial fix.

---

Comment by xiaoge1001 on 2023-06-12 04:06:40+00:00:
Does anyone care about this?

---

Comment by Mightyjo on 2023-06-13 12:46:29+00:00:
Short answer: nfa.c is working as intended. 

Looks like the failing input comes from a fuzzer. It consists of around 16KB of *s in a row, plus some other junk.

The crash occurs in flex itself, not the scanner produced by flex. The protection against exploit is to not run flex setuid. This is already the default.

I'm not very concerned that we see stack exhaustion when someone feeds exceptionally long garbage input to flex. Detecting that before processing would require solving the halting problem so we just have to begin. If there's a cleaner way to fail, I'm glad to hear it of course. Also, if there's a smaller, more realistic POC that would be something to consider.

Attachments:
https://github.com/westes/flex/files/2739794/POC.zip

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
export ASAN_OPTIONS="detect_leaks=0"
./autogen.sh
./configure
make V=1 -j$(nproc)

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y make autoconf automake libtool m4 gettext help2man bison autopoint lzip texinfo texlive flex
RUN git clone https://github.com/westes/flex flex
RUN git -C flex checkout ab49343b08c933e32de8de78132649f9560a3727
WORKDIR $SRC/flex
COPY build.sh $SRC/

Additional files:
filename: flex-patch.diff
content: diff --git a/src/main.c b/src/main.c
index eb2c09f..bab11db 100644
--- a/src/main.c
+++ b/src/main.c
@@ -38,7 +38,7 @@
 #include "tables.h"
 #include "parse.h"
 
-static char flex_version[] = FLEX_VERSION;
+static char flex_version[] ="ran";// FLEX_VERSION;
 
 /* declare functions that have forward references */
 
@@ -144,17 +144,18 @@ int flex_main (int argc, char *argv[])
 			fflush(stdout);
 			fclose(stdout);
 		}
+		return 0;
+		/*
 		while (wait(&child_status) > 0){
 			if (!WIFEXITED (child_status)
 			    || WEXITSTATUS (child_status) != 0){
-				/* report an error of a child
-				 */
 				if( exit_status <= 1 )
 					exit_status = 2;
 
 			}
 		}
 		return exit_status - 1;
+		*/
 	}
 
 	flexinit (argc, argv);
@@ -271,7 +272,7 @@ int flex_main (int argc, char *argv[])
 }
 
 /* Wrapper around flex_main, so flex_main can be built as a library. */
-int main (int argc, char *argv[])
+int main2 (int argc, char *argv[])
 {
 #if defined(ENABLE_NLS) && ENABLE_NLS
 #if HAVE_LOCALE_H
@@ -293,7 +294,7 @@ void initialize_output_filters(void)
 
 	output_chain = filter_create_int(NULL, filter_tee_header, env.headerfilename);
 	if ( !(m4 = getenv("M4"))) {
-		m4 = M4;
+		m4 = NULL;
 	}
 	filter_create_ext(output_chain, m4, "-P", (char *) 0);
 	filter_create_int(output_chain, filter_fix_linedirs, NULL);

filename: fuzz-main.c
content: /* Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
      http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "flexdef.h"
#include "options.h"
#include "scanopt.h"

char *my_argv[3];

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  char filename[256];
  sprintf(filename, "/tmp/libfuzzer.%d", getpid());

  FILE *fp = fopen(filename, "wb");
  if (!fp) {
    return 0;
  }
  fwrite(data, size, 1, fp);
  fclose(fp);

  my_argv[0] = "/tmp/fakefuzzer";
  my_argv[1] = filename;
  my_argv[2] = NULL;

  flex_main(2, my_argv);

  unlink(filename);
  return 0;
}

filename: fuzz-main.options
content: [libfuzzer]
detect_leaks=0

filename: fuzz-scanopt.c
content: /* Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
      http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "flexdef.h"
#include "options.h"
#include "scanopt.h"

char *my_argv[4];

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  if (size < 24) {
    return 0;
  }
  char *opt_fuzz = malloc(24);

  memcpy(opt_fuzz, data, 23);
  opt_fuzz[23] = 0;
  data += 23;
  size -= 23;

  char *new_str = (char *)malloc(size + 1);
  if (new_str == NULL) {
    return 0;
  }
  memcpy(new_str, data, size);
  new_str[size] = '\0';
  my_argv[0] = "/tmp/fuzz/";
  my_argv[1] = opt_fuzz;
  my_argv[2] = new_str;
  my_argv[3] = NULL;

  scanopt_t sopt;
  sopt = scanopt_init(flexopts, 3, my_argv, 0);
  if (!sopt) {
    free(new_str);
    free(opt_fuzz);
    return 0;
  }
  int optind;
  char *arg;
  scanopt(sopt, &arg, &optind);
  scanopt_destroy(sopt);

  free(new_str);
  free(opt_fuzz);
  return 0;
}