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 "../libdriver/driver.h"
|
||||
#include <sys/ioc_memory.h>
|
||||
#include <env.h>
|
||||
#include <minix/ds.h>
|
||||
#include "../../kernel/const.h"
|
||||
#include "../../kernel/config.h"
|
||||
|
@ -140,6 +141,11 @@ int safe; /* safe copies */
|
|||
|
||||
static int n = 0;
|
||||
|
||||
if(!safe) {
|
||||
printf("m_transfer: unsafe?\n");
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
if (ex64hi(pos64) != 0)
|
||||
return OK; /* Beyond EOF */
|
||||
position= cv64ul(pos64);
|
||||
|
@ -170,21 +176,11 @@ int safe; /* safe copies */
|
|||
seg = m_seg[m_device];
|
||||
|
||||
if (opcode == DEV_GATHER_S) { /* copy actual data */
|
||||
if(safe) {
|
||||
r=sys_safecopyto(proc_nr, user_vir, vir_offset,
|
||||
position, count, seg);
|
||||
} else {
|
||||
r=sys_vircopy(SELF,seg,position,
|
||||
proc_nr,D,user_vir+vir_offset, count);
|
||||
}
|
||||
} else {
|
||||
if(safe) {
|
||||
r=sys_safecopyfrom(proc_nr, user_vir, vir_offset,
|
||||
position, count, seg);
|
||||
} else {
|
||||
r=sys_vircopy(proc_nr,D,user_vir+vir_offset,
|
||||
SELF,seg,position, count);
|
||||
}
|
||||
}
|
||||
if(r != OK) {
|
||||
panic("MEM","I/O copy failed",r);
|
||||
|
@ -193,10 +189,18 @@ int safe; /* safe copies */
|
|||
|
||||
/* Physical copying. Only used to access entire memory. */
|
||||
case MEM_DEV:
|
||||
if (position >= dv_size) return(OK); /* check for EOF */
|
||||
if (position + count > dv_size) count = dv_size - position;
|
||||
if (position >= dv_size) {
|
||||
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;
|
||||
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) {
|
||||
panic("MEM","sys_umap failed in m_transfer",r);
|
||||
}
|
||||
|
@ -217,14 +221,8 @@ int safe; /* safe copies */
|
|||
left = count;
|
||||
while (left > 0) {
|
||||
chunk = (left > ZERO_BUF_SIZE) ? ZERO_BUF_SIZE : left;
|
||||
if(safe) {
|
||||
s=sys_safecopyto(proc_nr, user_vir,
|
||||
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)
|
||||
report("MEM","sys_vircopy failed", s);
|
||||
left -= chunk;
|
||||
|
@ -238,21 +236,11 @@ int safe; /* safe copies */
|
|||
if (position + count > dv_size) count = dv_size - position;
|
||||
|
||||
if (opcode == DEV_GATHER_S) { /* copy actual data */
|
||||
if(safe) {
|
||||
s=sys_safecopyto(proc_nr, user_vir, vir_offset,
|
||||
(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 {
|
||||
if(safe) {
|
||||
s=sys_safecopyfrom(proc_nr, user_vir, vir_offset,
|
||||
(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;
|
||||
|
||||
|
@ -304,11 +292,28 @@ PRIVATE void m_init()
|
|||
u32_t ramdev_base;
|
||||
message m;
|
||||
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))) {
|
||||
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. */
|
||||
m_geom[KMEM_DEV].dv_base = cvul64(kinfo.kmem_base);
|
||||
m_geom[KMEM_DEV].dv_size = cvul64(kinfo.kmem_size);
|
||||
|
@ -350,13 +355,8 @@ PRIVATE void m_init()
|
|||
dev_zero[i] = '\0';
|
||||
}
|
||||
|
||||
/* Set up memory ranges for /dev/mem. */
|
||||
#if (CHIP == INTEL)
|
||||
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) */
|
||||
/* Set up memory range for /dev/mem. */
|
||||
m_geom[MEM_DEV].dv_size = cvul64(mem_top);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
@ -372,6 +372,11 @@ int safe;
|
|||
*/
|
||||
struct device *dv;
|
||||
|
||||
if(!safe) {
|
||||
printf("m_transfer: unsafe?\n");
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
switch (m_ptr->REQUEST) {
|
||||
case MIOCRAMSIZE: {
|
||||
/* Someone wants to create a new RAM disk with the given size. */
|
||||
|
@ -391,14 +396,8 @@ int safe;
|
|||
ramdev_size= m_ptr->POSITION;
|
||||
#else
|
||||
/* Get request structure */
|
||||
if(safe) {
|
||||
s= sys_safecopyfrom(m_ptr->IO_ENDPT, (vir_bytes)m_ptr->IO_GRANT,
|
||||
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)
|
||||
return s;
|
||||
#endif
|
||||
|
@ -448,13 +447,8 @@ int safe;
|
|||
do_map= (m_ptr->REQUEST == MIOCMAP); /* else unmap */
|
||||
|
||||
/* Get request structure */
|
||||
if(safe) {
|
||||
r= sys_safecopyfrom(m_ptr->IO_ENDPT, (vir_bytes)m_ptr->IO_GRANT,
|
||||
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)
|
||||
return r;
|
||||
|
@ -480,4 +474,3 @@ struct partition *entry;
|
|||
entry->heads = 64;
|
||||
entry->sectors = 32;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue