Hardened memory bounds check
This commit is contained in:
		@@ -50,7 +50,7 @@ void mem_write8(uint32_t address, uint8_t value)
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			if(io->reg_size == 1)
 | 
								if(io->reg_size == 1)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
                void (*fn_write)(uint32_t, uint8_t) = io->fn_write;
 | 
									void (*fn_write)(uint32_t, uint8_t) = io->fn_write;
 | 
				
			||||||
				fn_write(address, value);
 | 
									fn_write(address, value);
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -63,6 +63,13 @@ void mem_write8(uint32_t address, uint8_t value)
 | 
				
			|||||||
		io = io->next;
 | 
							io = io->next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if we are inside of physical memory
 | 
				
			||||||
 | 
						if(address + 1 > memory_size)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fprintf(stderr, "MEMORY: Invalid write of size 1 outside of physical memory at address 0x%x\n", address);
 | 
				
			||||||
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Proceed with memory write
 | 
						// Proceed with memory write
 | 
				
			||||||
	pthread_mutex_lock(&memory_mutex);
 | 
						pthread_mutex_lock(&memory_mutex);
 | 
				
			||||||
	memory[address] = value;
 | 
						memory[address] = value;
 | 
				
			||||||
@@ -81,7 +88,7 @@ void mem_write16(uint32_t address, uint16_t value)
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			if(io->reg_size == 2)
 | 
								if(io->reg_size == 2)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
                void (*fn_write)(uint32_t, uint16_t) = io->fn_write;
 | 
									void (*fn_write)(uint32_t, uint16_t) = io->fn_write;
 | 
				
			||||||
				fn_write(address, value);
 | 
									fn_write(address, value);
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -94,6 +101,13 @@ void mem_write16(uint32_t address, uint16_t value)
 | 
				
			|||||||
		io = io->next;
 | 
							io = io->next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if we are inside of physical memory
 | 
				
			||||||
 | 
						if(address + 2 > memory_size)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fprintf(stderr, "MEMORY: Invalid write of size 2 outside of physical memory at address 0x%x\n", address);
 | 
				
			||||||
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Proceed with memory write
 | 
						// Proceed with memory write
 | 
				
			||||||
	pthread_mutex_lock(&memory_mutex);
 | 
						pthread_mutex_lock(&memory_mutex);
 | 
				
			||||||
	*((uint16_t*) &memory[address]) = value;
 | 
						*((uint16_t*) &memory[address]) = value;
 | 
				
			||||||
@@ -112,7 +126,7 @@ void mem_write32(uint32_t address, uint32_t value)
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			if(io->reg_size == 4)
 | 
								if(io->reg_size == 4)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
                void (*fn_write)(uint32_t, uint32_t) = io->fn_write;
 | 
									void (*fn_write)(uint32_t, uint32_t) = io->fn_write;
 | 
				
			||||||
				fn_write(address, value);
 | 
									fn_write(address, value);
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -125,6 +139,13 @@ void mem_write32(uint32_t address, uint32_t value)
 | 
				
			|||||||
		io = io->next;
 | 
							io = io->next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if we are inside of physical memory
 | 
				
			||||||
 | 
						if(address + 4 > memory_size)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fprintf(stderr, "MEMORY: Invalid write of size 1 outside of physical memory at address 0x%x\n", address);
 | 
				
			||||||
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Proceed with memory write
 | 
						// Proceed with memory write
 | 
				
			||||||
	pthread_mutex_lock(&memory_mutex);
 | 
						pthread_mutex_lock(&memory_mutex);
 | 
				
			||||||
	*((uint32_t*) &memory[address]) = value;
 | 
						*((uint32_t*) &memory[address]) = value;
 | 
				
			||||||
@@ -135,7 +156,7 @@ uint8_t mem_read8(uint32_t address)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	address = mmu_resolve(cpu0, READ, address);
 | 
						address = mmu_resolve(cpu0, READ, address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Look wether we are on an MMIO region
 | 
						// Look wether we are on an MMIO region
 | 
				
			||||||
	struct MMIO_ENTRY* io = mmio;
 | 
						struct MMIO_ENTRY* io = mmio;
 | 
				
			||||||
	while(io)
 | 
						while(io)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -143,7 +164,7 @@ uint8_t mem_read8(uint32_t address)
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			if(io->reg_size == 1)
 | 
								if(io->reg_size == 1)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
                uint8_t (*fn_read)(uint32_t) = io->fn_read;
 | 
									uint8_t (*fn_read)(uint32_t) = io->fn_read;
 | 
				
			||||||
				return fn_read(address);
 | 
									return fn_read(address);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
@@ -155,18 +176,25 @@ uint8_t mem_read8(uint32_t address)
 | 
				
			|||||||
		io = io->next;
 | 
							io = io->next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if we are inside of physical memory
 | 
				
			||||||
 | 
						if(address + 1 > memory_size)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fprintf(stderr, "MEMORY: Invalid read of size 1 outside of physical memory at address 0x%x\n", address);
 | 
				
			||||||
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Proceed with memory read
 | 
						// Proceed with memory read
 | 
				
			||||||
	pthread_mutex_lock(&memory_mutex);
 | 
						pthread_mutex_lock(&memory_mutex);
 | 
				
			||||||
	uint8_t tr = memory[address];
 | 
						uint8_t tr = memory[address];
 | 
				
			||||||
	pthread_mutex_unlock(&memory_mutex);
 | 
						pthread_mutex_unlock(&memory_mutex);
 | 
				
			||||||
    return tr;
 | 
						return tr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t mem_read16(uint32_t address)
 | 
					uint16_t mem_read16(uint32_t address)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	address = mmu_resolve(cpu0, READ, address);
 | 
						address = mmu_resolve(cpu0, READ, address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Look wether we are on an MMIO region
 | 
						// Look wether we are on an MMIO region
 | 
				
			||||||
	struct MMIO_ENTRY* io = mmio;
 | 
						struct MMIO_ENTRY* io = mmio;
 | 
				
			||||||
	while(io)
 | 
						while(io)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -174,7 +202,7 @@ uint16_t mem_read16(uint32_t address)
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			if(io->reg_size == 2)
 | 
								if(io->reg_size == 2)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
                uint16_t (*fn_read)(uint32_t) = io->fn_read;
 | 
									uint16_t (*fn_read)(uint32_t) = io->fn_read;
 | 
				
			||||||
				return fn_read(address);
 | 
									return fn_read(address);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
@@ -186,18 +214,25 @@ uint16_t mem_read16(uint32_t address)
 | 
				
			|||||||
		io = io->next;
 | 
							io = io->next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if we are inside of physical memory
 | 
				
			||||||
 | 
						if(address + 2 > memory_size)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fprintf(stderr, "MEMORY: Invalid read of size 2 outside of physical memory at address 0x%x\n", address);
 | 
				
			||||||
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Proceed with memory read
 | 
						// Proceed with memory read
 | 
				
			||||||
	pthread_mutex_lock(&memory_mutex);
 | 
						pthread_mutex_lock(&memory_mutex);
 | 
				
			||||||
	uint16_t tr = *((uint16_t*) &memory[address]);
 | 
						uint16_t tr = *((uint16_t*) &memory[address]);
 | 
				
			||||||
	pthread_mutex_unlock(&memory_mutex);
 | 
						pthread_mutex_unlock(&memory_mutex);
 | 
				
			||||||
    return tr;
 | 
						return tr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t mem_read32(uint32_t address)
 | 
					uint32_t mem_read32(uint32_t address)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	address = mmu_resolve(cpu0, READ, address);
 | 
						address = mmu_resolve(cpu0, READ, address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Look wether we are on an MMIO region
 | 
						// Look wether we are on an MMIO region
 | 
				
			||||||
	struct MMIO_ENTRY* io = mmio;
 | 
						struct MMIO_ENTRY* io = mmio;
 | 
				
			||||||
	while(io)
 | 
						while(io)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -205,7 +240,7 @@ uint32_t mem_read32(uint32_t address)
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			if(io->reg_size == 4)
 | 
								if(io->reg_size == 4)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
                uint32_t (*fn_read)(uint32_t) = io->fn_read;
 | 
									uint32_t (*fn_read)(uint32_t) = io->fn_read;
 | 
				
			||||||
				return fn_read(address);
 | 
									return fn_read(address);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
@@ -217,18 +252,25 @@ uint32_t mem_read32(uint32_t address)
 | 
				
			|||||||
		io = io->next;
 | 
							io = io->next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if we are inside of physical memory
 | 
				
			||||||
 | 
						if(address + 4 > memory_size)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fprintf(stderr, "MEMORY: Invalid read of size 4 outside of physical memory at address 0x%x\n", address);
 | 
				
			||||||
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Proceed with memory read
 | 
						// Proceed with memory read
 | 
				
			||||||
	pthread_mutex_lock(&memory_mutex);
 | 
						pthread_mutex_lock(&memory_mutex);
 | 
				
			||||||
	uint32_t tr = *((uint32_t*) &memory[address]);
 | 
						uint32_t tr = *((uint32_t*) &memory[address]);
 | 
				
			||||||
	pthread_mutex_unlock(&memory_mutex);
 | 
						pthread_mutex_unlock(&memory_mutex);
 | 
				
			||||||
    return tr;
 | 
						return tr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t mem_fetch(uint32_t address)
 | 
					uint32_t mem_fetch(uint32_t address)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	address = mmu_resolve(cpu0, INSTRUCTION_FETCH, address);
 | 
						address = mmu_resolve(cpu0, INSTRUCTION_FETCH, address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Look wether we are on an MMIO region
 | 
						// Look wether we are on an MMIO region
 | 
				
			||||||
	struct MMIO_ENTRY* io = mmio;
 | 
						struct MMIO_ENTRY* io = mmio;
 | 
				
			||||||
	while(io)
 | 
						while(io)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -240,9 +282,16 @@ uint32_t mem_fetch(uint32_t address)
 | 
				
			|||||||
		io = io->next;
 | 
							io = io->next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if we are inside of physical memory
 | 
				
			||||||
 | 
						if(address + 4 > memory_size)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fprintf(stderr, "MEMORY: Invalid fetch outside of physical memory at address 0x%x\n", address);
 | 
				
			||||||
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Proceed with memory read
 | 
						// Proceed with memory read
 | 
				
			||||||
	pthread_mutex_lock(&memory_mutex);
 | 
						pthread_mutex_lock(&memory_mutex);
 | 
				
			||||||
	uint32_t tr = *((uint32_t*) &memory[address]);
 | 
						uint32_t tr = *((uint32_t*) &memory[address]);
 | 
				
			||||||
	pthread_mutex_unlock(&memory_mutex);
 | 
						pthread_mutex_unlock(&memory_mutex);
 | 
				
			||||||
    return tr;
 | 
						return tr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user