Skip to content

Commit 565552d

Browse files
Fixed #8048: Crash with SIGBUS when there is no free space on the partition with memory-mapped files
1 parent 17edd37 commit 565552d

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

src/common/isc_sync.cpp

100644100755
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,51 @@ void SharedMemoryBase::unlinkFile(const TEXT* expanded_filename) noexcept
11681168

11691169
#ifdef UNIX
11701170

1171+
static inline void reportError(const char* func, CheckStatusWrapper* statusVector)
1172+
{
1173+
if (!statusVector)
1174+
system_call_failed::raise(func);
1175+
else
1176+
error(statusVector, func, errno);
1177+
}
1178+
1179+
bool allocFileSpace(int fd, off_t offset, FB_SIZE_T length, CheckStatusWrapper* statusVector)
1180+
{
1181+
#if defined(HAVE_LINUX_FALLOC_H) && defined(HAVE_FALLOCATE)
1182+
if (fallocate(fd, 0, offset, length))
1183+
{
1184+
reportError("fallocate", statusVector);
1185+
return false;
1186+
}
1187+
#else
1188+
static const FB_SIZE_T buf128KSize = 131072;
1189+
HalfStaticArray<UCHAR, BUFFER_LARGE> buf;
1190+
const FB_SIZE_T bufSize = length < buf128KSize ? length : buf128KSize;
1191+
1192+
memset(buf.getBuffer(bufSize), 0, bufSize);
1193+
os_utils::lseek(fd, LSEEK_OFFSET_CAST offset, SEEK_SET);
1194+
1195+
while (length)
1196+
{
1197+
const FB_SIZE_T cnt = length < bufSize ? length : bufSize;
1198+
if (write(fd, buf.begin(), cnt) != (ssize_t) cnt)
1199+
{
1200+
reportError("write", statusVector);
1201+
return false;
1202+
}
1203+
length -= cnt;
1204+
}
1205+
1206+
if (fsync(fd))
1207+
{
1208+
reportError("fsync", statusVector);
1209+
return false;
1210+
}
1211+
#endif
1212+
return true;
1213+
}
1214+
1215+
11711216
void SharedMemoryBase::internalUnmap()
11721217
{
11731218
if (sh_mem_header)
@@ -1303,7 +1348,10 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
13031348
if (mainLock->setlock(&statusVector, FileLock::FLM_TRY_EXCLUSIVE))
13041349
{
13051350
if (trunc_flag)
1351+
{
13061352
FB_UNUSED(os_utils::ftruncate(mainLock->getFd(), length));
1353+
allocFileSpace(mainLock->getFd(), 0, length, NULL);
1354+
}
13071355

13081356
if (callback->initialize(this, true))
13091357
{
@@ -2436,8 +2484,19 @@ bool SharedMemoryBase::remapFile(CheckStatusWrapper* statusVector, ULONG new_len
24362484
}
24372485

24382486
if (flag)
2487+
{
24392488
FB_UNUSED(os_utils::ftruncate(mainLock->getFd(), new_length));
24402489

2490+
if (new_length > sh_mem_length_mapped)
2491+
{
2492+
if (!allocFileSpace(mainLock->getFd(), sh_mem_length_mapped,
2493+
new_length - sh_mem_length_mapped, statusVector))
2494+
{
2495+
return false;
2496+
}
2497+
}
2498+
}
2499+
24412500
MemoryHeader* const address = (MemoryHeader*) os_utils::mmap(0, new_length,
24422501
PROT_READ | PROT_WRITE, MAP_SHARED, mainLock->getFd(), 0);
24432502

0 commit comments

Comments
 (0)