Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle "stack overflow" panic on huge input with regex functions #525

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

msoap
Copy link

@msoap msoap commented Feb 19, 2025

On some input data we got "stack overflow" panic in the regex string functions (string.match, string.gsub, string.find, ...).
It seems that recursion depends on the length of the input string because we run Regexp functions on the user-generated data and can encounter huge strings.

In the code (https://github.com/yuin/gopher-lua/blob/master/pm/pm.go#L611) i see panic recovering, but "stack overflow" cannot catch.

Panic example:

runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc05df58328 stack=[0xc05df58000, 0xc07df58000]
fatal error: stack overflow

runtime stack:
runtime.throw({0x14e4620?, 0x7f72367fbd70?})
        /home/app/go/src/runtime/panic.go:1067 +0x48 fp=0x7f72367fbd30 sp=0x7f72367fbd00 pc=0x4768a8
runtime.newstack()
        /home/app/go/src/runtime/stack.go:1117 +0x5bd fp=0x7f72367fbe70 sp=0x7f72367fbd30 pc=0x458e5d
runtime.morestack()
        /home/app/go/src/runtime/asm_amd64.s:621 +0x7a fp=0x7f72367fbe78 sp=0x7f72367fbe70 pc=0x47d21a

goroutine 135038 gp=0xc00263ddc0 m=11 mp=0xc000600008 [running]:
runtime.deductAssistCredit(0x8?)
        /home/app/go/src/runtime/malloc.go:1333 +0x70 fp=0xc05df58338 sp=0xc05df58330 pc=0x412390
runtime.mallocgc(0x8, 0x12b61a0, 0x1)
        /home/app/go/src/runtime/malloc.go:1037 +0xde fp=0xc05df583d8 sp=0xc05df58338 pc=0x470e9e
runtime.newobject(0xc00dcf5f80?)
        /home/app/go/src/runtime/malloc.go:1386 +0x25 fp=0xc05df58400 sp=0xc05df583d8 pc=0x412465
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df58568?, {0xc00dcf5aa0, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x1fe fp=0xc05df584c0 sp=0xc05df58400 pc=0xb4151e
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df58628?, {0xc00dcf5a98, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df58580 sp=0xc05df584c0 pc=0xb4159c
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df586e8?, {0xc00dcf5a90, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df58640 sp=0xc05df58580 pc=0xb4159c
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df587a8?, {0xc00dcf5a88, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df58700 sp=0xc05df58640 pc=0xb4159c
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df58868?, {0xc00dcf5a80, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df587c0 sp=0xc05df58700 pc=0xb4159c
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df58928?, {0xc00dcf5a78, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df58880 sp=0xc05df587c0 pc=0xb4159c
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df589e8?, {0xc00dcf5a70, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df58940 sp=0xc05df58880 pc=0xb4159c
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df58aa8?, {0xc00dcf5a68, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df58a00 sp=0xc05df58940 pc=0xb4159c
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df58b68?, {0xc00dcf5a60, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df58ac0 sp=0xc05df58a00 pc=0xb4159c
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df58c28?, {0xc00dcf5a58, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df58b80 sp=0xc05df58ac0 pc=0xb4159c
...
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df5a728?, {0xc00dcf5938, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df5a680 sp=0xc05df5a5c0 pc=0xb4159c
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc05df5a7e8?, {0xc00dcf5930, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc05df5a740 sp=0xc05df5a680 pc=0xb4159c
...2796101 frames elided...
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc001ff3c68?, {0xc005998658, 0x1, ...})
        /home/app/go/pkg/mod/github.com/yuin/[email protected]/pm/pm.go:552 +0x27c fp=0xc07df55bc0 sp=0xc07df55b00 pc=0xb4159c
github.com/yuin/gopher-lua/pm.recursiveVM({0xc02905c000, 0x5a841c, 0x5a841c}, {0xc0028b9088, 0xa, 0x11}, 0x8?, 0xc001ff3d28?, {0xc005998650, 0x1, ...})
...

Reproduction example:

package main

import (
	"log"

	lua "github.com/yuin/gopher-lua"
)

func main() {
	L := lua.NewState()
	defer L.Close()

	script := `
		re = '"(.+)"'
		bigstr = string.rep('{"a": "b"},', 1000000)
		m = string.match(bigstr, re)
		print(m)
	`
	if err := L.DoString(script); err != nil {
		log.Fatalf("Error running lua code: %v", err)
	}
}

So, I propose to limit the recursion level to 100000.

Possible consequences: we can got error on huge strings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant