Made reading and writing memory overflow safe.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13306 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2005-06-28 11:19:30 +00:00
parent a87826801c
commit 07b6630b86
1 changed files with 31 additions and 16 deletions

View File

@ -999,27 +999,38 @@ read_user_memory(const void *_address, void *_buffer, int32 size,
// If the region to be read crosses page boundaries, we split it up into
// smaller chunks.
status_t error = B_OK;
bytesRead = 0;
while (size > 0) {
int32 toRead = size;
if ((uint32)address % B_PAGE_SIZE + toRead > B_PAGE_SIZE)
toRead = B_PAGE_SIZE - (uint32)address % B_PAGE_SIZE;
status_t error = user_memcpy(buffer, address, toRead);
// If reading fails, we only fail, if we haven't read anything yet.
if (error != B_OK) {
if (bytesRead > 0)
return B_OK;
return error;
// check whether we're still in user address space
if (!IS_USER_ADDRESS(address)) {
error = B_BAD_ADDRESS;
break;
}
// don't cross page boundaries in a single read
int32 toRead = size;
int32 maxRead = B_PAGE_SIZE - (addr_t)address % B_PAGE_SIZE;
if (toRead > maxRead)
toRead = maxRead;
error = user_memcpy(buffer, address, toRead);
if (error != B_OK)
break;
bytesRead += toRead;
address += toRead;
buffer += toRead;
size -= toRead;
}
// If reading fails, we only fail, if we haven't read anything yet.
if (error != B_OK) {
if (bytesRead > 0)
return B_OK;
return error;
}
return B_OK;
}
@ -1042,7 +1053,11 @@ write_user_memory(void *_address, const void *_buffer, int32 size,
status_t error = B_OK;
bytesWritten = 0;
while (size > 0) {
int32 toWrite = size;
// check whether we're still in user address space
if (!IS_USER_ADDRESS(address)) {
error = B_BAD_ADDRESS;
break;
}
// get the area for the address (we need to use _user_area_for(), since
// we're looking for a user area)
@ -1064,10 +1079,10 @@ write_user_memory(void *_address, const void *_buffer, int32 size,
}
// restrict this round of writing to the found area
if (toWrite > (int32)areaInfo.size)
toWrite = areaInfo.size;
if (address + toWrite > (char*)areaInfo.address + areaInfo.size)
toWrite = (char*)areaInfo.address + areaInfo.size - address;
int32 toWrite = size;
int32 maxWrite = (char*)areaInfo.address + areaInfo.size - address;
if (toWrite > maxWrite)
toWrite = maxWrite;
// if the area is read-only, we temporarily need to make it writable
bool protectionChanged = false;