Add check for max mmap size.

The max mmap size was previous unchecked which resulted in a panic once
the maximum size was reached. This commit adds a check for the max size
when re-mapping and returns an error if the new map will exceed the size.

Thanks to Tamás Gulácsi for testing out the change on i386.
master
Ben Johnson 2015-01-12 08:06:42 -07:00
parent a12b668bf7
commit 8374d6adc5
1 changed files with 15 additions and 10 deletions

25
db.go
View File

@ -162,16 +162,6 @@ func (db *DB) mmap(minsz int) error {
db.mmaplock.Lock() db.mmaplock.Lock()
defer db.mmaplock.Unlock() defer db.mmaplock.Unlock()
// Dereference all mmap references before unmapping.
if db.rwtx != nil {
db.rwtx.root.dereference()
}
// Unmap existing data before continuing.
if err := db.munmap(); err != nil {
return err
}
info, err := db.file.Stat() info, err := db.file.Stat()
if err != nil { if err != nil {
return fmt.Errorf("mmap stat error: %s", err) return fmt.Errorf("mmap stat error: %s", err)
@ -186,6 +176,21 @@ func (db *DB) mmap(minsz int) error {
} }
size = db.mmapSize(size) size = db.mmapSize(size)
// Verify the map size is not above the maximum allowed.
if size > maxMapSize {
return fmt.Errorf("mmap too large")
}
// Dereference all mmap references before unmapping.
if db.rwtx != nil {
db.rwtx.root.dereference()
}
// Unmap existing data before continuing.
if err := db.munmap(); err != nil {
return err
}
// Memory-map the data file as a byte slice. // Memory-map the data file as a byte slice.
if err := mmap(db, size); err != nil { if err := mmap(db, size); err != nil {
return err return err