boltdb/bolt

application crash if db file is corrupted

cbrake opened this issue · 2 comments

If I delete a few bytes from the beginning of a bolt db file, I get an application seg fault:

pwlog-test
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4a4348]

goroutine 1 [running]:
bec.com/vendor/github.com/boltdb/bolt.(*DB).Close(0x0, 0x0, 0x0)
        /scratch/go/src/bec.com/vendor/github.com/boltdb/bolt/db.go:392 +0x38
main.main()
        /scratch/go/src/bec.com/cmd/pwlog-test/pwlog-test.go:26 +0x1ea
exit status 2

This is probably expected, but I'm wondering if there is any way to run a check on the file so we can handle the errors in the application (perhaps reset the db file, etc)?

Thanks!

+1

I try to do recover like the following and still not able to recover

defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("Access problem")
}
}()

aimof commented

I try this problem.

bolt/db.go

Line 809 in 9da3174

if db.meta1.txid > db.meta0.txid {

the error is occured in this line because db.meta0 and db.meta1 is nil.

This is the code i tried to cause panic.

func main() {
	db, err := bolt.Open("my.db", 0600, nil)
	if err != nil {
		log.Fatalln(err)
	}

	f, err := os.OpenFile("my.db", os.O_RDWR, 0600)
	if err != nil {
		log.Fatalln(err)
	}

	if err = f.Truncate(11); err != nil {
		log.Fatalln(err)
	}

	if err = f.Close(); err != nil {
		log.Fatalln(err)
	}

	err = db.View(func(tx *bolt.Tx) error { // this line causes an error!
		return nil
	})
	if err != nil {
		log.Fatalln(err)
	}

	if err = db.Close(); err != nil {
		log.Fatalln(err)
	}
}

so, we should check the meta0 and meta1 exist or not if we want to solve this issue.