kernel: add secalloc() and secfree() functions for secret memory allocation
The kernel needs to keep cryptographic keys and cipher states confidential. secalloc() allocates memory from the secret pool which is protected from debuggers reading the memory thru devproc. secfree() releases the memory, overriding the data with garbage.
This commit is contained in:
parent
8a73650874
commit
0f97eb3a60
3 changed files with 55 additions and 6 deletions
|
@ -53,8 +53,27 @@ static Pool pimagmem = {
|
|||
.private= &pimagpriv,
|
||||
};
|
||||
|
||||
static Private psecrpriv;
|
||||
static Pool psecrmem = {
|
||||
.name= "Secrets",
|
||||
.maxsize= 16*1024*1024,
|
||||
.minarena= 64*1024,
|
||||
.quantum= 32,
|
||||
.alloc= xalloc,
|
||||
.merge= xmerge,
|
||||
.flags= POOL_ANTAGONISM,
|
||||
|
||||
.lock= plock,
|
||||
.unlock= punlock,
|
||||
.print= poolprint,
|
||||
.panic= ppanic,
|
||||
|
||||
.private= &psecrpriv,
|
||||
};
|
||||
|
||||
Pool* mainmem = &pmainmem;
|
||||
Pool* imagmem = &pimagmem;
|
||||
Pool* secrmem = &psecrmem;
|
||||
|
||||
/*
|
||||
* because we can't print while we're holding the locks,
|
||||
|
@ -129,6 +148,7 @@ mallocsummary(void)
|
|||
{
|
||||
poolsummary(mainmem);
|
||||
poolsummary(imagmem);
|
||||
poolsummary(secrmem);
|
||||
}
|
||||
|
||||
/* everything from here down should be the same in libc, libdebugmalloc, and the kernel */
|
||||
|
@ -171,12 +191,9 @@ smalloc(ulong size)
|
|||
{
|
||||
void *v;
|
||||
|
||||
for(;;) {
|
||||
v = poolalloc(mainmem, size+Npadlong*sizeof(ulong));
|
||||
if(v != nil)
|
||||
break;
|
||||
while((v = poolalloc(mainmem, size+Npadlong*sizeof(ulong))) == nil){
|
||||
if(!waserror()){
|
||||
resrcwait(0);
|
||||
resrcwait(nil);
|
||||
poperror();
|
||||
}
|
||||
}
|
||||
|
@ -278,6 +295,34 @@ calloc(ulong n, ulong szelem)
|
|||
return v;
|
||||
}
|
||||
|
||||
/* secret memory, used to back cryptographic keys and cipher states */
|
||||
void*
|
||||
secalloc(ulong size)
|
||||
{
|
||||
void *v;
|
||||
|
||||
while((v = poolalloc(secrmem, size+Npadlong*sizeof(ulong))) == nil){
|
||||
if(!waserror()){
|
||||
resrcwait(nil);
|
||||
poperror();
|
||||
}
|
||||
}
|
||||
if(Npadlong){
|
||||
v = (ulong*)v+Npadlong;
|
||||
setmalloctag(v, getcallerpc(&size));
|
||||
setrealloctag(v, 0);
|
||||
}
|
||||
memset(v, 0, size);
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
secfree(void *v)
|
||||
{
|
||||
if(v != nil)
|
||||
poolfree(secrmem, (ulong*)v-Npadlong);
|
||||
}
|
||||
|
||||
void
|
||||
setmalloctag(void *v, uintptr pc)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "ureg.h"
|
||||
#include "edf.h"
|
||||
|
||||
#include <pool.h>
|
||||
|
||||
enum
|
||||
{
|
||||
Qdir,
|
||||
|
@ -789,7 +791,7 @@ procread(Chan *c, void *va, long n, vlong off)
|
|||
if(addr < KZERO)
|
||||
return procctlmemio(c, p, addr, va, n, 1);
|
||||
|
||||
if(!iseve())
|
||||
if(!iseve() || poolisoverlap(secrmem, (uchar*)addr, n))
|
||||
error(Eperm);
|
||||
|
||||
/* validate kernel addresses */
|
||||
|
|
|
@ -308,6 +308,8 @@ void sched(void);
|
|||
void scheddump(void);
|
||||
void schedinit(void);
|
||||
void (*screenputs)(char*, int);
|
||||
void* secalloc(ulong);
|
||||
void secfree(void*);
|
||||
long seconds(void);
|
||||
uintptr segattach(int, char *, uintptr, uintptr);
|
||||
void segclock(uintptr);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue