Example #1
0
void doit( void )
{
	volatile char *buf;
	fptr func;

	buf = malloc( 1 );
	if( buf == NULL ) {
		fprintf( stderr, "Out of memory\n" );
		exit( 1 );
	}

	/* Put a RETN instruction in the buffer */
	*buf = '\xc3';

	/* Try to make the buffer executable by using mprotect() */
	/* Due to a FreeBSD bug PROT_READ is required */
	do_mprotect( buf, 1, PROT_READ|PROT_EXEC );

	/* Convert the pointer to a function pointer */
	func = (fptr)buf;

	/* Call the code in the buffer */
	func();

	do_mprotect( buf, 1, PROT_READ|PROT_WRITE );

	/* It worked when the function returns */
	itworked();
}
Example #2
0
void doit( void )
{
	char *shbss;
	char *shbss2;
	fptr func;
	void *handle1, *handle2;

	handle1 = dlopen( "shlibtest.so", RTLD_LAZY );
	if( handle1 == NULL ) {
		fprintf( stderr, "dlopen() returned NULL\n" );
		exit( 1 );
	}
	dlerror(); /* clear any errors */
	shbss = dlsym( handle1, "shbss" );
	if( dlerror() != NULL ) {
		fprintf( stderr, "symbol %s not found in %s\n", "shbss", "shlibtest.so" );
		exit( 1 );
	}

	handle2 = dlopen( "shlibtest2.so", RTLD_LAZY );
	if( handle2 == NULL ) {
		fprintf( stderr, "dlopen() returned NULL\n" );
		exit( 1 );
	}
	dlerror(); /* clear any errors */
	shbss2 = dlsym( handle2, "shbss2" );
	if( dlerror() != NULL ) {
		fprintf( stderr, "symbol %s not found in %s\n", "shbss2", "shlibtest2.so" );
		exit( 1 );
	}

	copy_shellcode(shbss, SHELLCODE_RETURN);
	copy_shellcode(shbss2, SHELLCODE_RETURN);

	/* Convert the pointer to a function pointer */
	func = shbss < shbss2 ? (fptr)shbss : (fptr)shbss2;

	/* Try to make the memory region executable by using mprotect() */
	/* Due to an OpenBSD bug PROT_READ is required */
	do_mprotect(func, MAX_SHELLCODE_LEN, PROT_READ|PROT_EXEC );

	/* Call the code in the buffer */
	func();

	do_mprotect(func, MAX_SHELLCODE_LEN, PROT_READ|PROT_WRITE );

	/* It worked when the function returns */
	itworked();

	dlclose( handle1 );
	dlclose( handle2 );
}
Example #3
0
int main(int argc, char *argv[]) {

	int ret = 0;
	int uid;

	if (argc != 2) {
		printf("Must run with one argument\n");
		exit(EXIT_FAILURE);
	}

	uid = atoi(argv[1]);

	if (!uid) {
		printf("Need to run this as a non-root user\n");
	}

	ret = setuid(uid);

	if (ret == -1) {
		perror("Unable to setuid");
		exit(EXIT_FAILURE);
	}

	ret = do_mmap(FILENAME);

	ret += do_mprotect(FILENAME);

	return ret;
}
Example #4
0
void doit( void )
{
	fptr func;

	/* Convert the pointer to a function pointer */
	func = (fptr)&buf;

	/* Try to make the data executable first by using mprotect */
	/* Due to an OpenBSD bug PROT_READ is required */
	do_mprotect( &buf, 1, PROT_READ|PROT_EXEC );

	/* Call the code in the buffer */
	func();

	do_mprotect( &buf, 1, PROT_READ|PROT_WRITE );

	/* It worked when the function returns */
	itworked();
}
Example #5
0
//Adding mprotect and munprotect here
int
mprotect(void *addr, int len)
{
	int ret = -1;
	uint addrint = (uint)addr;
    //Checks if page-aligned
   if (addrint % PGSIZE != 0) 
   {
    return ret;
   }
  
   //Check if addr is not too large
   /*
   int procint = *proc;
   if ( (*addrint +len) > (procint + proc->sz) ) 
   {
    return -1;
   }
   */

   //cprintf("%s%d\n", "lengthoutside = ", len);
   if(len <= 0)	
   {
		//cprintf("%s%d\n", "lengthinside = ", len);
		//cprintf("-1 on 1\n");
	  	return ret;
   }

   if(addrint + (len * PGSIZE) > proc->sz)
   {
	  //cprintf("-1 on 2\n");
	  return ret;
   }

   if(addrint  > proc->sz || addrint <= 0)
   {
      //cprintf("-1 on 3\n");
	  return ret;
   }

	//NOT SURE IF WE NEED ALL THIS CODE(or what it does) -CONOR
   //int pid = proc->pid;
   //int *addrint = addr;
   //acquire(&ptable.lock);
   //if (pid < 0 || pid >= NPROC) {
    //   release(&ptable.lock); 
	//   return ret;
  // }

   
   ret = 0;
   do_mprotect(proc, addr);

   return ret;
}
Example #6
0
static uint32_t
__sys_linux_mprotect(uint32_t arg[])
{
	
	void *addr = (void*)arg[0];
	size_t len = arg[1];
	int prot = arg[2];

	//kprintf("mprotect addr=0x%08x len=%08x prot=%08x\n", addr, len, prot);

	return do_mprotect(addr, len, prot);
}
Example #7
0
int kern_mprotect(void * addr, int len) {
	if ((uint)addr % PGSIZE != 0)
		return -1;
	//  another check needed: addr too large
	if  ((uint)addr <= 0 || (uint)addr > proc->sz)
		return -1;
	if  (len <= 0 || (len*PGSIZE)+(int)addr > proc->sz)
		return -1;

	
	acquire(&ptable.lock);
    do_mprotect(proc, (int)addr, len);
    release(&ptable.lock);
    return 0;
}
Example #8
0
int
kern_mprotect(void *addr, int len){
    if((int)addr % PGSIZE != 0)
        return -1;
    if((int)addr >= proc->sz || (int)addr + 4 > proc->sz)
        return -1;
    if(len <= 0)
        return -1;
    if((int)addr + (len * PGSIZE) > proc->sz)
       return -1;
    if(addr == 0)
        return -1;
    do_mprotect((void*)addr,len);
    return 0;
}
Example #9
0
int kern_mprotect(struct proc* process, void *addr, int len) {
	unsigned int start = (unsigned int) addr;

	//bounds checking
	if (addr == 0) return -1; // fail on null address

	if (start % PGSIZE != 0) return -1;
	if (start > process->sz) return -1;
	if (len <= 0) return -1;
	if ((start + PGSIZE*len) > process->sz) return -1;

	int i;
	for (i = start; i < start + (len * PGSIZE); i+= PGSIZE) {
		if (do_mprotect(process, (void*) i) == -1)
			return -1; // propagate -1 to user process
	}
	lcr3(v2p(process->pgdir));
	return 0;
}
Example #10
0
uintptr_t sys_mprotect(uintptr_t addr, size_t length, int prot)
{
  return do_mprotect(addr, length, prot);
}
static ssize_t write_proc_mm(struct file *file, const char *buffer,
			     size_t count, loff_t *ppos)
{
	struct mm_struct *mm = file->private_data;
	struct proc_mm_op req;
	int n, ret;

	if(count > sizeof(req))
		return(-EINVAL);

	n = copy_from_user(&req, buffer, count);
	if(n != 0)
		return(-EFAULT);

	ret = count;
	switch(req.op){
	case MM_MMAP: {
		struct mm_mmap *map = &req.u.mmap;

		ret = do_mmap2(mm, map->addr, map->len, map->prot, 
			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
		if((ret & ~PAGE_MASK) == 0)
			ret = count;
	
		break;
	}
	case MM_MUNMAP: {
		struct mm_munmap *unmap = &req.u.munmap;

		down_write(&mm->mmap_sem);
		ret = do_munmap(mm, unmap->addr, unmap->len);
		up_write(&mm->mmap_sem);

		if(ret == 0)
			ret = count;
		break;
	}
	case MM_MPROTECT: {
		struct mm_mprotect *protect = &req.u.mprotect;

		ret = do_mprotect(mm, protect->addr, protect->len, 
				  protect->prot);
		if(ret == 0)
			ret = count;
		break;
	}

	case MM_COPY_SEGMENTS: {
		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);

		if(IS_ERR(from)){
			ret = PTR_ERR(from);
			break;
		}

		mm_copy_segments(from, mm);
		break;
	}
	default:
		ret = -EINVAL;
		break;
	}

	return(ret);
}
Example #12
0
void load_elf(const char* fn, elf_info* info)
{
  file_t* file = file_open(fn, O_RDONLY, 0);
  if (IS_ERR_VALUE(file))
    goto fail;

  Elf_Ehdr eh;
  ssize_t ehdr_size = file_pread(file, &eh, sizeof(eh), 0);
  if (ehdr_size < (ssize_t)sizeof(eh) ||
      !(eh.e_ident[0] == '\177' && eh.e_ident[1] == 'E' &&
        eh.e_ident[2] == 'L'    && eh.e_ident[3] == 'F'))
    goto fail;

#if __riscv_xlen == 64
  assert(IS_ELF64(eh));
#else
  assert(IS_ELF32(eh));
#endif

#ifndef __riscv_compressed
  assert(!(eh.e_flags & EF_RISCV_RVC));
#endif

  size_t phdr_size = eh.e_phnum * sizeof(Elf_Phdr);
  if (phdr_size > info->phdr_size)
    goto fail;
  ssize_t ret = file_pread(file, (void*)info->phdr, phdr_size, eh.e_phoff);
  if (ret < (ssize_t)phdr_size)
    goto fail;
  info->phnum = eh.e_phnum;
  info->phent = sizeof(Elf_Phdr);
  Elf_Phdr* ph = (typeof(ph))info->phdr;

  // compute highest VA in ELF
  uintptr_t max_vaddr = 0;
  for (int i = 0; i < eh.e_phnum; i++)
    if (ph[i].p_type == PT_LOAD && ph[i].p_memsz)
      max_vaddr = MAX(max_vaddr, ph[i].p_vaddr + ph[i].p_memsz);
  max_vaddr = ROUNDUP(max_vaddr, RISCV_PGSIZE);

  // don't load dynamic linker at 0, else we can't catch NULL pointer derefs
  uintptr_t bias = 0;
  if (eh.e_type == ET_DYN)
    bias = RISCV_PGSIZE;

  info->entry = eh.e_entry + bias;
  int flags = MAP_FIXED | MAP_PRIVATE;
  for (int i = eh.e_phnum - 1; i >= 0; i--) {
    if(ph[i].p_type == PT_LOAD && ph[i].p_memsz) {
      uintptr_t prepad = ph[i].p_vaddr % RISCV_PGSIZE;
      uintptr_t vaddr = ph[i].p_vaddr + bias;
      if (vaddr + ph[i].p_memsz > info->brk_min)
        info->brk_min = vaddr + ph[i].p_memsz;
      int flags2 = flags | (prepad ? MAP_POPULATE : 0);
      int prot = get_prot(ph[i].p_flags);
      if (__do_mmap(vaddr - prepad, ph[i].p_filesz + prepad, prot | PROT_WRITE, flags2, file, ph[i].p_offset - prepad) != vaddr - prepad)
        goto fail;
      memset((void*)vaddr - prepad, 0, prepad);
      if (!(prot & PROT_WRITE))
        if (do_mprotect(vaddr - prepad, ph[i].p_filesz + prepad, prot))
          goto fail;
      size_t mapped = ROUNDUP(ph[i].p_filesz + prepad, RISCV_PGSIZE) - prepad;
      if (ph[i].p_memsz > mapped)
        if (__do_mmap(vaddr + mapped, ph[i].p_memsz - mapped, prot, flags|MAP_ANONYMOUS, 0, 0) != vaddr + mapped)
          goto fail;
    }
  }

  file_decref(file);
  return;

fail:
  panic("couldn't open ELF program: %s!", fn);
}