[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Problem with LIST_HEAD and list_add (was Page Fault Handler Hijacking and Oops)
> > The exception handler function hijacked:
> >
> > 15. static asmlinkage void mtpmc_handler(struct pt_regs * regs,
> > long error_code)
> >
> I am not actually sure this is supposed to work. asmlinkage changes the
> calling convention so I would expect simply calling it to not work. But
> I don't know the calling convention tricks well enough to be sure. Also
> note, that in 2.6.9 it is asmlinkage, but in 2.6.11 it is fastcall.
>
> Also are you sure %%cr2 does not get destroyed before you call this. It
> shouldn't be, but anyway.
I'm not using 2.6.X but 2.4.29. It's asmlinkage.
For the %%cr2, it seems to go well. Infact, if I comment the if line:
if (mtpmc_protected_by_us(address) == 1)
all run. The error seems to be in that function.
I'm just modifying my code using the <linux/list.h> macros but I'm having some
problems also with it. In particular, with the creation of the lists.
I attach the modified lines of code.
The data structures become:
struct mtpmc_wrprotected_pages{ /* CREARE LIST_HEAD */
struct list_head list;
unsigned long address;
};
struct mtpmc_vm_wrprotected{ /* CREARE LIST_HEAD */
struct list_head list;
unsigned long vm_start;
unsigned long vm_end;
struct mtpmc_wrprotected_pages *pages;
};
the function to scans these list is:
int mtpmc_protected_by_us(unsigned long addr)
{
struct list_head *vm_list, *page_list;
struct mtpmc_vm_wrprotected *wr_vma;
struct mtpmc_wrprotected_pages *wr_page, *temp_page;
list_for_each(vm_list, &vm_write_protected){
wr_vma = list_entry(vm_list, struct mtpmc_vm_wrprotected, list);
if (INSIDE(wr_vma->vm_start, wr_vma->vm_end, addr)){
temp_page = wr_vma->pages;
list_for_each(page_list, &temp_page->list){
wr_page = list_entry(page_list, struct mtpmc_wrprotected_pages, list);
if ((addr >= wr_page->address) && (addr <(wr_page->address + PAGE_SIZE)))
return 1;
}
return 0;
}
}
return 0;
}
But the real problem is with the creation of one of the lists. The function in
which I create them is the following:
0. static LIST_HEAD(vm_write_protected);
1. void mtpmc_set_mm_not_writable(struct mm_struct *mm)
2. {
3. struct vm_area_struct *vm;
4. struct mtpmc_wrprotected_pages *wr_page, *temp_page_wr;
5. struct mtpmc_vm_wrprotected *temp_vma_wr;
6. struct page *page;
7. pte_t *pte;
8. unsigned long addr;
9.
10. down_write(&mm->mmap_sem);
11. for (vm = mm->mmap; vm!=NULL; vm=vm->vm_next)
12. if(mtpmc_vm_to_save(mm, vm) == 1){
13. temp_vma_wr = mtpmc_mk_vm_wrprotected(vm);
14. list_add_tail(&temp_vma_wr->list, &vm_write_protected);
15. wr_page = temp_vma_wr->pages;
16. INIT_LIST_HEAD(&wr_page->list);
17. for(addr=vm->vm_start;addr<vm->vm_end;addr+=PAGE_SIZE){
18. pte = mtpmc_get_pte_from_address(mm, addr);
19. if (pte)
20. if (pte_write(*pte)){
21. set_pte(pte, pte_wrprotect(*pte));
22. list_add_tail(&mtpmc_mk_page_wrprotected(addr)->list,
&wr_page->list);
23. }
24. }
25. up_write(&mm->mmap_sem);
26.
27. return;
28. }
the problem is with INIT_LIST_HEAD in line 16. I receive an error "Unable to
handle NULL pointer ..." but the pointers in this function are never NULL.
For sake of completeness I post also the two function for creation of
temp_vma_wr (called from line 13 - mtpmc_mk_vm_wrprotected(vm) ) and to
create a new temp page (called from line 22 -
mtpmc_mk_page_wrprotected(addr) ).
Can you help me in organizing my data structures with the use of Linux
list_head?
>
> Anyway, I suspect the problem might be the call to the original handler.
>
> Also make sure you properly lock the list with irqsaving spinlocks (ie.
> spin_lock_irqsave/spin_unlock_irqrestore outside the handler and
> spin_lock/spin_unlock inside.
>
I don't use spin_lock as I'm created a uniprocessor program.
Thanks.
Vincenzo Mallozzi.
___________________________________
Yahoo! Mail: gratis 1GB per i messaggi e allegati da 10MB
http://mail.yahoo.it
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/