/*by Breno S. Pinto*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NUM_mysyscallmem 230 extern void *sys_call_table[]; asmlinkage unsigned long (*original_call) (int numero,unsigned long address); asmlinkage unsigned long my_syscallmem(int numero,unsigned long address); struct page *my_teste_page_alloc_mem(struct vm_area_struct *vma,unsigned long address,int unused) { struct page *page; page = alloc_page(GFP_USER); if(!page) { printk("<2>Can not alloc new page\n"); return NOPAGE_OOM; } return page; } struct vm_operations_struct my_vm_operation = { nopage: my_teste_page_alloc_mem, }; asmlinkage unsigned long my_syscallmem(int numero,unsigned long address) { unsigned long end; unsigned long len; unsigned int flags; unsigned int vmflags; struct vm_area_struct *vma; struct mm_struct *mm = current->mm; flags = MAP_ANON; len = PAGE_ALIGN(numero); down_write(¤t->mm->mmap_sem); address = get_unmapped_area(NULL,address,len,0,flags); if(!address) { printk("<2>Can not define start address\n"); return -ENOMEM; } end = address + len; if(end > TASK_SIZE) { printk("<2>No memory\n"); return -ENOMEM; } vma = kmem_cache_alloc(vm_area_cachep,SLAB_KERNEL); if(!vma) return -ENOMEM; vmflags = mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_WRITE | VM_READ; vma->vm_mm = mm; vma->vm_start = address; /*Start address*/ vma->vm_end = end; /*Final address*/ vma->vm_ops = &my_vm_operation; vma->vm_flags = vmflags; vma->vm_pgoff = 0; vma->vm_file = NULL; /*MAP_NON*/ vma->vm_private_data = NULL; vma->vm_raend = 0; vma->vm_page_prot = protection_map[vmflags & 0x0f]; insert_vm_struct(mm,vma); up_write(¤t->mm->mmap_sem); return address; } int init_module() { original_call = sys_call_table[NUM_mysyscallmem]; sys_call_table[NUM_mysyscallmem] = my_syscallmem; return 0; } int cleanup_module() { sys_call_table[NUM_mysyscallmem] = original_call; return 0; }