mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-06 01:32:50 -06:00
on POSIX systems use mprotect to protect the data from accidental changes
This commit is contained in:
@@ -163,7 +163,7 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
#ifndef MREMAP_MAYMOVE
|
#ifndef MREMAP_MAYMOVE
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
ms = (malloc_state*)
|
ms = (malloc_state*)
|
||||||
mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
mmap(NULL, mmap_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
if (ms == MAP_FAILED) {
|
if (ms == MAP_FAILED) {
|
||||||
code = errno;
|
code = errno;
|
||||||
ms = NULL; // mark that ms is not created.
|
ms = NULL; // mark that ms is not created.
|
||||||
@@ -173,6 +173,14 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
throw pgf_systemerror(code, filepath);
|
throw pgf_systemerror(code, filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mprotect(ms, page_size, PROT_READ | PROT_WRITE) == -1) {
|
||||||
|
code = errno;
|
||||||
|
munmap(ms,mmap_size);
|
||||||
|
::free((void *) this->filepath);
|
||||||
|
close(fd);
|
||||||
|
throw pgf_systemerror(code, filepath);
|
||||||
|
}
|
||||||
|
|
||||||
mmap_size -= page_size;
|
mmap_size -= page_size;
|
||||||
base = ((unsigned char *) ms) + page_size;
|
base = ((unsigned char *) ms) + page_size;
|
||||||
} else {
|
} else {
|
||||||
@@ -189,7 +197,7 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
#else
|
#else
|
||||||
int mflags = (fd < 0) ? (MAP_PRIVATE | MAP_ANONYMOUS) : MAP_SHARED;
|
int mflags = (fd < 0) ? (MAP_PRIVATE | MAP_ANONYMOUS) : MAP_SHARED;
|
||||||
ms = (malloc_state*)
|
ms = (malloc_state*)
|
||||||
mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, mflags, fd, 0);
|
mmap(NULL, mmap_size, PROT_READ, mflags, fd, 0);
|
||||||
if (ms == MAP_FAILED) {
|
if (ms == MAP_FAILED) {
|
||||||
code = errno;
|
code = errno;
|
||||||
ms = NULL; // mark that ms is not created.
|
ms = NULL; // mark that ms is not created.
|
||||||
@@ -199,6 +207,14 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
throw pgf_systemerror(code, filepath);
|
throw pgf_systemerror(code, filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mprotect(ms, page_size, PROT_READ | PROT_WRITE) == -1) {
|
||||||
|
code = errno;
|
||||||
|
munmap(ms,mmap_size);
|
||||||
|
::free((void *) this->filepath);
|
||||||
|
close(fd);
|
||||||
|
throw pgf_systemerror(code, filepath);
|
||||||
|
}
|
||||||
|
|
||||||
mmap_size -= page_size;
|
mmap_size -= page_size;
|
||||||
base = ((unsigned char *) ms) + page_size;
|
base = ((unsigned char *) ms) + page_size;
|
||||||
#endif
|
#endif
|
||||||
@@ -678,6 +694,7 @@ int PgfDB::init_state()
|
|||||||
ms->free_blocks = 0;
|
ms->free_blocks = 0;
|
||||||
ms->free_descriptors = 0;
|
ms->free_descriptors = 0;
|
||||||
ms->n_revisions = 0;
|
ms->n_revisions = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,7 +729,7 @@ PGF_INTERNAL_DECL object PgfDB::new_block_descr(object o, size_t size, txn_t txn
|
|||||||
size_t new_size =
|
size_t new_size =
|
||||||
ms->file_size + alloc_size;
|
ms->file_size + alloc_size;
|
||||||
|
|
||||||
resize_map(new_size);
|
resize_map(new_size, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
odescr = top;
|
odescr = top;
|
||||||
@@ -768,7 +785,7 @@ object PgfDB::upd_block_descr(object map, object left, object right)
|
|||||||
size_t new_size =
|
size_t new_size =
|
||||||
ms->file_size + alloc_size;
|
ms->file_size + alloc_size;
|
||||||
|
|
||||||
resize_map(new_size);
|
resize_map(new_size, true);
|
||||||
|
|
||||||
// refresh the pointer
|
// refresh the pointer
|
||||||
descr = ptr(block_descr, map);
|
descr = ptr(block_descr, map);
|
||||||
@@ -1181,7 +1198,7 @@ object PgfDB::malloc_internal(size_t bytes)
|
|||||||
size_t new_size =
|
size_t new_size =
|
||||||
ms->file_size + alloc_size;
|
ms->file_size + alloc_size;
|
||||||
|
|
||||||
resize_map(new_size);
|
resize_map(new_size, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
o = top;
|
o = top;
|
||||||
@@ -1217,7 +1234,7 @@ object PgfDB::realloc_internal(object oldo, size_t old_bytes, size_t new_bytes,
|
|||||||
size_t new_size =
|
size_t new_size =
|
||||||
ms->file_size + alloc_size;
|
ms->file_size + alloc_size;
|
||||||
|
|
||||||
resize_map(new_size);
|
resize_map(new_size, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the object is at the end of the allocation area
|
// If the object is at the end of the allocation area
|
||||||
@@ -1388,6 +1405,14 @@ void PgfDB::start_transaction()
|
|||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
pthread_mutex_lock(&ms->write_mutex);
|
pthread_mutex_lock(&ms->write_mutex);
|
||||||
|
|
||||||
|
if (
|
||||||
|
#ifndef MREMAP_MAYMOVE
|
||||||
|
fd >= 0 &&
|
||||||
|
#endif
|
||||||
|
mprotect(base, mmap_size, PROT_READ | PROT_WRITE) == -1)
|
||||||
|
throw pgf_systemerror(errno);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
WaitForSingleObject(hWriteMutex, INFINITE);
|
WaitForSingleObject(hWriteMutex, INFINITE);
|
||||||
#endif
|
#endif
|
||||||
@@ -1456,6 +1481,9 @@ void PgfDB::commit(object o)
|
|||||||
ms->free_descriptors = free_descriptors[0];
|
ms->free_descriptors = free_descriptors[0];
|
||||||
ms->curr_txn_id++;
|
ms->curr_txn_id++;
|
||||||
|
|
||||||
|
if (mprotect(base, mmap_size, PROT_READ) == -1)
|
||||||
|
throw pgf_systemerror(errno);
|
||||||
|
|
||||||
res = msync((void *) ms, page_size, MS_SYNC | MS_INVALIDATE);
|
res = msync((void *) ms, page_size, MS_SYNC | MS_INVALIDATE);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
ms->active_revision = save_active_revision;
|
ms->active_revision = save_active_revision;
|
||||||
@@ -1465,6 +1493,7 @@ void PgfDB::commit(object o)
|
|||||||
ms->curr_txn_id--;
|
ms->curr_txn_id--;
|
||||||
throw pgf_systemerror(errno);
|
throw pgf_systemerror(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MREMAP_MAYMOVE
|
#ifndef MREMAP_MAYMOVE
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1514,6 +1543,13 @@ void PgfDB::rollback()
|
|||||||
last_free_block_txn_id = 0;
|
last_free_block_txn_id = 0;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
if (
|
||||||
|
#ifndef MREMAP_MAYMOVE
|
||||||
|
fd >= 0 &&
|
||||||
|
#endif
|
||||||
|
mprotect(base, mmap_size, PROT_READ) == -1)
|
||||||
|
throw pgf_systemerror(errno);
|
||||||
|
|
||||||
pthread_mutex_unlock(&ms->write_mutex);
|
pthread_mutex_unlock(&ms->write_mutex);
|
||||||
#else
|
#else
|
||||||
ReleaseMutex(hWriteMutex);
|
ReleaseMutex(hWriteMutex);
|
||||||
@@ -1601,7 +1637,7 @@ void PgfDB::lock(DB_scope_mode m)
|
|||||||
|
|
||||||
// If another process has resized the file we must resize the map
|
// If another process has resized the file we must resize the map
|
||||||
if (mmap_size != ms->file_size)
|
if (mmap_size != ms->file_size)
|
||||||
resize_map(ms->file_size);
|
resize_map(ms->file_size, m == WRITER_SCOPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfDB::unlock()
|
void PgfDB::unlock()
|
||||||
@@ -1630,7 +1666,7 @@ void PgfDB::unlock()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfDB::resize_map(size_t new_size)
|
void PgfDB::resize_map(size_t new_size, bool writeable)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
int res;
|
int res;
|
||||||
@@ -1649,8 +1685,9 @@ void PgfDB::resize_map(size_t new_size)
|
|||||||
if (ftruncate(fd, page_size+new_size) < 0)
|
if (ftruncate(fd, page_size+new_size) < 0)
|
||||||
throw pgf_systemerror(errno, filepath);
|
throw pgf_systemerror(errno, filepath);
|
||||||
}
|
}
|
||||||
new_base =
|
int prot = writeable ? PROT_READ | PROT_WRITE : PROT_READ;
|
||||||
(unsigned char *) mmap(0, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_size);
|
new_base =
|
||||||
|
(unsigned char *) mmap(0, new_size, prot, MAP_SHARED, fd, page_size);
|
||||||
if (new_base == MAP_FAILED)
|
if (new_base == MAP_FAILED)
|
||||||
throw pgf_systemerror(errno);
|
throw pgf_systemerror(errno);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ private:
|
|||||||
PGF_INTERNAL_DECL void lock(DB_scope_mode m);
|
PGF_INTERNAL_DECL void lock(DB_scope_mode m);
|
||||||
PGF_INTERNAL_DECL void unlock();
|
PGF_INTERNAL_DECL void unlock();
|
||||||
|
|
||||||
PGF_INTERNAL_DECL void resize_map(size_t new_size);
|
PGF_INTERNAL_DECL void resize_map(size_t new_size, bool writeable);
|
||||||
|
|
||||||
friend class DB_scope;
|
friend class DB_scope;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user