don't let /dev/mem read beyond top of physical memory
This commit is contained in:
parent
49d2195722
commit
654f6faf05
1 changed files with 41 additions and 48 deletions
|
@ -17,6 +17,7 @@
|
||||||
#include "../drivers.h"
|
#include "../drivers.h"
|
||||||
#include "../libdriver/driver.h"
|
#include "../libdriver/driver.h"
|
||||||
#include <sys/ioc_memory.h>
|
#include <sys/ioc_memory.h>
|
||||||
|
#include <env.h>
|
||||||
#include <minix/ds.h>
|
#include <minix/ds.h>
|
||||||
#include "../../kernel/const.h"
|
#include "../../kernel/const.h"
|
||||||
#include "../../kernel/config.h"
|
#include "../../kernel/config.h"
|
||||||
|
@ -140,6 +141,11 @@ int safe; /* safe copies */
|
||||||
|
|
||||||
static int n = 0;
|
static int n = 0;
|
||||||
|
|
||||||
|
if(!safe) {
|
||||||
|
printf("m_transfer: unsafe?\n");
|
||||||
|
return EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
if (ex64hi(pos64) != 0)
|
if (ex64hi(pos64) != 0)
|
||||||
return OK; /* Beyond EOF */
|
return OK; /* Beyond EOF */
|
||||||
position= cv64ul(pos64);
|
position= cv64ul(pos64);
|
||||||
|
@ -170,21 +176,11 @@ int safe; /* safe copies */
|
||||||
seg = m_seg[m_device];
|
seg = m_seg[m_device];
|
||||||
|
|
||||||
if (opcode == DEV_GATHER_S) { /* copy actual data */
|
if (opcode == DEV_GATHER_S) { /* copy actual data */
|
||||||
if(safe) {
|
|
||||||
r=sys_safecopyto(proc_nr, user_vir, vir_offset,
|
r=sys_safecopyto(proc_nr, user_vir, vir_offset,
|
||||||
position, count, seg);
|
position, count, seg);
|
||||||
} else {
|
|
||||||
r=sys_vircopy(SELF,seg,position,
|
|
||||||
proc_nr,D,user_vir+vir_offset, count);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(safe) {
|
|
||||||
r=sys_safecopyfrom(proc_nr, user_vir, vir_offset,
|
r=sys_safecopyfrom(proc_nr, user_vir, vir_offset,
|
||||||
position, count, seg);
|
position, count, seg);
|
||||||
} else {
|
|
||||||
r=sys_vircopy(proc_nr,D,user_vir+vir_offset,
|
|
||||||
SELF,seg,position, count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(r != OK) {
|
if(r != OK) {
|
||||||
panic("MEM","I/O copy failed",r);
|
panic("MEM","I/O copy failed",r);
|
||||||
|
@ -193,10 +189,18 @@ int safe; /* safe copies */
|
||||||
|
|
||||||
/* Physical copying. Only used to access entire memory. */
|
/* Physical copying. Only used to access entire memory. */
|
||||||
case MEM_DEV:
|
case MEM_DEV:
|
||||||
if (position >= dv_size) return(OK); /* check for EOF */
|
if (position >= dv_size) {
|
||||||
if (position + count > dv_size) count = dv_size - position;
|
printf("memory: read 0x%lx beyond physical memory of 0x%lx\n",
|
||||||
|
position, dv_size);
|
||||||
|
return(OK); /* check for EOF */
|
||||||
|
}
|
||||||
|
if (position + count > dv_size) {
|
||||||
|
printf("memory: truncating count from %d to ", count);
|
||||||
|
count = dv_size - position;
|
||||||
|
printf("%d (size %d)\n", count, dv_size);
|
||||||
|
}
|
||||||
mem_phys = cv64ul(dv->dv_base) + position;
|
mem_phys = cv64ul(dv->dv_base) + position;
|
||||||
if((r=sys_umap(proc_nr, safe ? GRANT_SEG : D, user_vir,
|
if((r=sys_umap(proc_nr, GRANT_SEG, user_vir,
|
||||||
count + vir_offset, &user_phys)) != OK) {
|
count + vir_offset, &user_phys)) != OK) {
|
||||||
panic("MEM","sys_umap failed in m_transfer",r);
|
panic("MEM","sys_umap failed in m_transfer",r);
|
||||||
}
|
}
|
||||||
|
@ -217,14 +221,8 @@ int safe; /* safe copies */
|
||||||
left = count;
|
left = count;
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
chunk = (left > ZERO_BUF_SIZE) ? ZERO_BUF_SIZE : left;
|
chunk = (left > ZERO_BUF_SIZE) ? ZERO_BUF_SIZE : left;
|
||||||
if(safe) {
|
|
||||||
s=sys_safecopyto(proc_nr, user_vir,
|
s=sys_safecopyto(proc_nr, user_vir,
|
||||||
vir_offset+suboffset, (vir_bytes) dev_zero, chunk, D);
|
vir_offset+suboffset, (vir_bytes) dev_zero, chunk, D);
|
||||||
} else {
|
|
||||||
s=sys_vircopy(SELF, D, (vir_bytes) dev_zero,
|
|
||||||
proc_nr, D, user_vir + vir_offset+suboffset,
|
|
||||||
chunk);
|
|
||||||
}
|
|
||||||
if(s != OK)
|
if(s != OK)
|
||||||
report("MEM","sys_vircopy failed", s);
|
report("MEM","sys_vircopy failed", s);
|
||||||
left -= chunk;
|
left -= chunk;
|
||||||
|
@ -238,21 +236,11 @@ int safe; /* safe copies */
|
||||||
if (position + count > dv_size) count = dv_size - position;
|
if (position + count > dv_size) count = dv_size - position;
|
||||||
|
|
||||||
if (opcode == DEV_GATHER_S) { /* copy actual data */
|
if (opcode == DEV_GATHER_S) { /* copy actual data */
|
||||||
if(safe) {
|
|
||||||
s=sys_safecopyto(proc_nr, user_vir, vir_offset,
|
s=sys_safecopyto(proc_nr, user_vir, vir_offset,
|
||||||
(vir_bytes)&imgrd[position], count, D);
|
(vir_bytes)&imgrd[position], count, D);
|
||||||
} else {
|
|
||||||
s=sys_vircopy(SELF, D, (vir_bytes)&imgrd[position],
|
|
||||||
proc_nr, D, user_vir+vir_offset, count);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(safe) {
|
|
||||||
s=sys_safecopyfrom(proc_nr, user_vir, vir_offset,
|
s=sys_safecopyfrom(proc_nr, user_vir, vir_offset,
|
||||||
(vir_bytes)&imgrd[position], count, D);
|
(vir_bytes)&imgrd[position], count, D);
|
||||||
} else {
|
|
||||||
s=sys_vircopy(proc_nr, D, user_vir+vir_offset,
|
|
||||||
SELF, D, (vir_bytes)&imgrd[position], count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -304,11 +292,28 @@ PRIVATE void m_init()
|
||||||
u32_t ramdev_base;
|
u32_t ramdev_base;
|
||||||
message m;
|
message m;
|
||||||
int i, s;
|
int i, s;
|
||||||
|
phys_bytes mem_top = 0;
|
||||||
|
|
||||||
|
/* Physical memory, to check validity of /dev/mem access. */
|
||||||
|
#define MAX_MEM_RANGES 10
|
||||||
|
struct memory mem_chunks[MAX_MEM_RANGES];
|
||||||
|
|
||||||
if (OK != (s=sys_getkinfo(&kinfo))) {
|
if (OK != (s=sys_getkinfo(&kinfo))) {
|
||||||
panic("MEM","Couldn't get kernel information.",s);
|
panic("MEM","Couldn't get kernel information.",s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Obtain physical memory chunks for /dev/mem memory. */
|
||||||
|
if(env_memory_parse(mem_chunks, MAX_MEM_RANGES) != OK)
|
||||||
|
printf("memory driver: no memory layout, /dev/mem won't work\n");
|
||||||
|
else {
|
||||||
|
for(i = 0; i < MAX_MEM_RANGES; i++) {
|
||||||
|
phys_bytes top;
|
||||||
|
top = mem_chunks[i].base + mem_chunks[i].size;
|
||||||
|
if(top > mem_top)
|
||||||
|
mem_top = top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Install remote segment for /dev/kmem memory. */
|
/* Install remote segment for /dev/kmem memory. */
|
||||||
m_geom[KMEM_DEV].dv_base = cvul64(kinfo.kmem_base);
|
m_geom[KMEM_DEV].dv_base = cvul64(kinfo.kmem_base);
|
||||||
m_geom[KMEM_DEV].dv_size = cvul64(kinfo.kmem_size);
|
m_geom[KMEM_DEV].dv_size = cvul64(kinfo.kmem_size);
|
||||||
|
@ -350,13 +355,8 @@ PRIVATE void m_init()
|
||||||
dev_zero[i] = '\0';
|
dev_zero[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up memory ranges for /dev/mem. */
|
/* Set up memory range for /dev/mem. */
|
||||||
#if (CHIP == INTEL)
|
m_geom[MEM_DEV].dv_size = cvul64(mem_top);
|
||||||
if (OK != (s=sys_getmachine(&machine))) {
|
|
||||||
panic("MEM","Couldn't get machine information.",s);
|
|
||||||
}
|
|
||||||
m_geom[MEM_DEV].dv_size = cvul64(0xFFFFFFFF); /* 4G-1 for 386 systems */
|
|
||||||
#endif /* !(CHIP == INTEL) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
@ -372,6 +372,11 @@ int safe;
|
||||||
*/
|
*/
|
||||||
struct device *dv;
|
struct device *dv;
|
||||||
|
|
||||||
|
if(!safe) {
|
||||||
|
printf("m_transfer: unsafe?\n");
|
||||||
|
return EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
switch (m_ptr->REQUEST) {
|
switch (m_ptr->REQUEST) {
|
||||||
case MIOCRAMSIZE: {
|
case MIOCRAMSIZE: {
|
||||||
/* Someone wants to create a new RAM disk with the given size. */
|
/* Someone wants to create a new RAM disk with the given size. */
|
||||||
|
@ -391,14 +396,8 @@ int safe;
|
||||||
ramdev_size= m_ptr->POSITION;
|
ramdev_size= m_ptr->POSITION;
|
||||||
#else
|
#else
|
||||||
/* Get request structure */
|
/* Get request structure */
|
||||||
if(safe) {
|
|
||||||
s= sys_safecopyfrom(m_ptr->IO_ENDPT, (vir_bytes)m_ptr->IO_GRANT,
|
s= sys_safecopyfrom(m_ptr->IO_ENDPT, (vir_bytes)m_ptr->IO_GRANT,
|
||||||
0, (vir_bytes)&ramdev_size, sizeof(ramdev_size), D);
|
0, (vir_bytes)&ramdev_size, sizeof(ramdev_size), D);
|
||||||
} else {
|
|
||||||
s= sys_vircopy(m_ptr->IO_ENDPT, D, (vir_bytes)m_ptr->ADDRESS,
|
|
||||||
SELF, D, (vir_bytes)&ramdev_size, sizeof(ramdev_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s != OK)
|
if (s != OK)
|
||||||
return s;
|
return s;
|
||||||
#endif
|
#endif
|
||||||
|
@ -448,13 +447,8 @@ int safe;
|
||||||
do_map= (m_ptr->REQUEST == MIOCMAP); /* else unmap */
|
do_map= (m_ptr->REQUEST == MIOCMAP); /* else unmap */
|
||||||
|
|
||||||
/* Get request structure */
|
/* Get request structure */
|
||||||
if(safe) {
|
|
||||||
r= sys_safecopyfrom(m_ptr->IO_ENDPT, (vir_bytes)m_ptr->IO_GRANT,
|
r= sys_safecopyfrom(m_ptr->IO_ENDPT, (vir_bytes)m_ptr->IO_GRANT,
|
||||||
0, (vir_bytes)&mapreq, sizeof(mapreq), D);
|
0, (vir_bytes)&mapreq, sizeof(mapreq), D);
|
||||||
} else {
|
|
||||||
r= sys_vircopy(m_ptr->IO_ENDPT, D, (vir_bytes)m_ptr->ADDRESS,
|
|
||||||
SELF, D, (vir_bytes)&mapreq, sizeof(mapreq));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
return r;
|
return r;
|
||||||
|
@ -480,4 +474,3 @@ struct partition *entry;
|
||||||
entry->heads = 64;
|
entry->heads = 64;
|
||||||
entry->sectors = 32;
|
entry->sectors = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue