mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-06 09:21:49 +00:00
nova: use 16bit for reference count of caps
Bomb and any server may generate references to capabilities exceeding 256 - use a 16bit counter until the cap handling in Genode gets unified. Additionally try to print a warning, instead of dying, if we get cap reference count under or overflow. Issue #1615
This commit is contained in:
parent
b1dd5fdf1d
commit
4ee8919f29
@ -39,10 +39,10 @@ namespace Genode {
|
|||||||
WORDS = (CAP_RANGE_SIZE - HEADER - sizeof(Avl_node<Cap_range>)) / sizeof(addr_t),
|
WORDS = (CAP_RANGE_SIZE - HEADER - sizeof(Avl_node<Cap_range>)) / sizeof(addr_t),
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t _cap_array[WORDS * sizeof(addr_t)];
|
uint16_t _cap_array[WORDS * sizeof(addr_t) / 2];
|
||||||
|
|
||||||
bool _match(addr_t id) {
|
bool _match(addr_t id) {
|
||||||
return _base <= id && id < _base + sizeof(_cap_array); };
|
return _base <= id && id < _base + elements(); };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -51,12 +51,12 @@ namespace Genode {
|
|||||||
static_assert(sizeof(*this) == CAP_RANGE_SIZE,
|
static_assert(sizeof(*this) == CAP_RANGE_SIZE,
|
||||||
"Cap_range misconfigured");
|
"Cap_range misconfigured");
|
||||||
|
|
||||||
for (unsigned i=0; i < sizeof(_cap_array); i++)
|
for (unsigned i = 0; i < elements(); i++)
|
||||||
_cap_array[i] = 0;
|
_cap_array[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t const base() const { return _base; }
|
addr_t const base() const { return _base; }
|
||||||
unsigned const elements() { return sizeof(_cap_array); }
|
unsigned const elements() { return sizeof(_cap_array) / sizeof(_cap_array[0]); }
|
||||||
|
|
||||||
Cap_range *find_by_id(addr_t);
|
Cap_range *find_by_id(addr_t);
|
||||||
|
|
||||||
|
39
repos/base-nova/src/base/env/cap_map.cc
vendored
39
repos/base-nova/src/base/env/cap_map.cc
vendored
@ -13,13 +13,16 @@
|
|||||||
|
|
||||||
#include <base/cap_map.h>
|
#include <base/cap_map.h>
|
||||||
|
|
||||||
|
#include <base/printf.h>
|
||||||
|
|
||||||
/* base-nova specific include */
|
/* base-nova specific include */
|
||||||
#include <nova/syscalls.h>
|
#include <nova/syscalls.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
Capability_map *Genode::cap_map() {
|
Capability_map *Genode::cap_map()
|
||||||
|
{
|
||||||
static Genode::Capability_map map;
|
static Genode::Capability_map map;
|
||||||
return ↦
|
return ↦
|
||||||
}
|
}
|
||||||
@ -39,35 +42,47 @@ Cap_range *Cap_range::find_by_id(addr_t id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Cap_range::inc(unsigned id, bool inc_if_one) {
|
void Cap_range::inc(unsigned id, bool inc_if_one)
|
||||||
|
{
|
||||||
|
bool failure = false;
|
||||||
|
{
|
||||||
Lock::Guard guard(_lock);
|
Lock::Guard guard(_lock);
|
||||||
|
|
||||||
if (inc_if_one && _cap_array[id] != 1)
|
if (inc_if_one && _cap_array[id] != 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_cap_array[id] == 255) {
|
if (_cap_array[id] + 1 == 0)
|
||||||
// PERR("cap overflow - selector %lx - return address %p",
|
failure = true;
|
||||||
// _base + id, __builtin_return_address(0));
|
else
|
||||||
*reinterpret_cast<addr_t *>(0) = 0xdead;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cap_array[id]++;
|
_cap_array[id]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (failure)
|
||||||
|
PERR("cap reference counting error - reference overflow of cap=%lx",
|
||||||
|
_base + id);
|
||||||
|
}
|
||||||
|
|
||||||
void Cap_range::dec(unsigned id, bool revoke) {
|
|
||||||
|
|
||||||
|
void Cap_range::dec(unsigned id, bool revoke)
|
||||||
|
{
|
||||||
|
bool failure = false;
|
||||||
|
{
|
||||||
Lock::Guard guard(_lock);
|
Lock::Guard guard(_lock);
|
||||||
|
|
||||||
if (_cap_array[id] == 0)
|
if (_cap_array[id] == 0)
|
||||||
*reinterpret_cast<addr_t *>(0) = 0xdead;
|
failure = true;
|
||||||
|
else {
|
||||||
if (revoke && _cap_array[id] == 1)
|
if (revoke && _cap_array[id] == 1)
|
||||||
Nova::revoke(Nova::Obj_crd(_base + id, 0));
|
Nova::revoke(Nova::Obj_crd(_base + id, 0));
|
||||||
|
|
||||||
_cap_array[id]--;
|
_cap_array[id]--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failure)
|
||||||
|
PERR("cap reference counting error - count of cap=%lx is already zero",
|
||||||
|
_base + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
addr_t Cap_range::alloc(size_t const num_log2)
|
addr_t Cap_range::alloc(size_t const num_log2)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user