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,
|
.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* mainmem = &pmainmem;
|
||||||
Pool* imagmem = &pimagmem;
|
Pool* imagmem = &pimagmem;
|
||||||
|
Pool* secrmem = &psecrmem;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* because we can't print while we're holding the locks,
|
* because we can't print while we're holding the locks,
|
||||||
|
@ -129,6 +148,7 @@ mallocsummary(void)
|
||||||
{
|
{
|
||||||
poolsummary(mainmem);
|
poolsummary(mainmem);
|
||||||
poolsummary(imagmem);
|
poolsummary(imagmem);
|
||||||
|
poolsummary(secrmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* everything from here down should be the same in libc, libdebugmalloc, and the kernel */
|
/* everything from here down should be the same in libc, libdebugmalloc, and the kernel */
|
||||||
|
@ -171,12 +191,9 @@ smalloc(ulong size)
|
||||||
{
|
{
|
||||||
void *v;
|
void *v;
|
||||||
|
|
||||||
for(;;) {
|
while((v = poolalloc(mainmem, size+Npadlong*sizeof(ulong))) == nil){
|
||||||
v = poolalloc(mainmem, size+Npadlong*sizeof(ulong));
|
|
||||||
if(v != nil)
|
|
||||||
break;
|
|
||||||
if(!waserror()){
|
if(!waserror()){
|
||||||
resrcwait(0);
|
resrcwait(nil);
|
||||||
poperror();
|
poperror();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,6 +295,34 @@ calloc(ulong n, ulong szelem)
|
||||||
return v;
|
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
|
void
|
||||||
setmalloctag(void *v, uintptr pc)
|
setmalloctag(void *v, uintptr pc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "ureg.h"
|
#include "ureg.h"
|
||||||
#include "edf.h"
|
#include "edf.h"
|
||||||
|
|
||||||
|
#include <pool.h>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
Qdir,
|
Qdir,
|
||||||
|
@ -789,7 +791,7 @@ procread(Chan *c, void *va, long n, vlong off)
|
||||||
if(addr < KZERO)
|
if(addr < KZERO)
|
||||||
return procctlmemio(c, p, addr, va, n, 1);
|
return procctlmemio(c, p, addr, va, n, 1);
|
||||||
|
|
||||||
if(!iseve())
|
if(!iseve() || poolisoverlap(secrmem, (uchar*)addr, n))
|
||||||
error(Eperm);
|
error(Eperm);
|
||||||
|
|
||||||
/* validate kernel addresses */
|
/* validate kernel addresses */
|
||||||
|
|
|
@ -308,6 +308,8 @@ void sched(void);
|
||||||
void scheddump(void);
|
void scheddump(void);
|
||||||
void schedinit(void);
|
void schedinit(void);
|
||||||
void (*screenputs)(char*, int);
|
void (*screenputs)(char*, int);
|
||||||
|
void* secalloc(ulong);
|
||||||
|
void secfree(void*);
|
||||||
long seconds(void);
|
long seconds(void);
|
||||||
uintptr segattach(int, char *, uintptr, uintptr);
|
uintptr segattach(int, char *, uintptr, uintptr);
|
||||||
void segclock(uintptr);
|
void segclock(uintptr);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue